0Pricing
C# Academy · บทเรียน

งานตามกำหนดเวลาด้วย Quartz.NET

กำหนดงานและทริกเกอร์ด้วย Quartz.NET ใช้นิพจน์ cron และผสานการทำงานกับ DI ของ ASP.NET Core

งานตามกำหนดเวลาด้วย Quartz.NET เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงใช้ Quartz.NET

เมื่อคุณต้องการนิพจน์ cron การคงอยู่ของงาน การทำงานเป็นคลัสเตอร์ นโยบายการลองใหม่ และห่วงโซ่งาน Quartz.NET จะมีตัวจัดกำหนดเวลาระดับพร้อมใช้งานจริงที่มีความสามารถมากกว่า PeriodicTimer โดยเป็นพอร์ตของตัวจัดกำหนดเวลา Java Quartz ยอดนิยมสำหรับ .NET

การติดตั้ง Quartz.NET

เพิ่มแพ็กเกจ Quartz และ Quartz.AspNetCore การผสานรวมกับ ASP.NET จะลงทะเบียนตัวจัดกำหนดเวลาเป็นบริการที่โฮสต์โดยอัตโนมัติ

# Install packages
dotnet add package Quartz
dotnet add package Quartz.AspNetCore

# Optional: persistence (requires Quartz.Serialization.Json too)
# dotnet add package Quartz.Jobs
# dotnet add package Quartz.Plugins

การกำหนดงาน

ใช้งาน IJob (หรือ IAsyncJob ใน Quartz รุ่นใหม่กว่า) พร้อมเมธอด Execute บริบทของงานจะมีข้อมูลขณะทำงานและข้อมูลของตัวกระตุ้นปัจจุบัน

using Quartz;

[DisallowConcurrentExecution] // prevent overlapping executions
public class ReportGeneratorJob : IJob
{
    private readonly IReportService _reports;
    private readonly ILogger<ReportGeneratorJob> _logger;

    public ReportGeneratorJob(IReportService r, ILogger<ReportGeneratorJob> l)
    { _reports = r; _logger = l; }

    public async Task Execute(IJobExecutionContext context)
    {
        _logger.LogInformation("Generating report at {Time}", DateTime.UtcNow);
        await _reports.GenerateDailyReportAsync(context.CancellationToken);
        _logger.LogInformation("Report generated");
    }
}

การลงทะเบียน Quartz ใน ASP.NET Core

ใช้ AddQuartz เพื่อกำหนดค่าตัวจัดกำหนดเวลา และใช้ AddQuartzHostedService เพื่อเรียกใช้เป็น IHostedService โดยกำหนดค่างานและตัวกระตุ้นไว้ใน lambda

builder.Services.AddQuartz(q =>
{
    q.UseMicrosoftDependencyInjectionJobFactory();

    var jobKey = new JobKey("ReportGenerator");
    q.AddJob<ReportGeneratorJob>(opts => opts.WithIdentity(jobKey));

    q.AddTrigger(opts => opts
        .ForJob(jobKey)
        .WithIdentity("ReportTrigger")
        .WithCronSchedule("0 0 8 * * ?") // 8:00 AM daily
    );
});

builder.Services.AddQuartzHostedService(q =>
    q.WaitForJobsToComplete = true);

ไวยากรณ์นิพจน์ Cron

Quartz ใช้นิพจน์ cron ที่มี 6 หรือ 7 ช่อง: seconds minutes hours day-of-month month day-of-week [year] cron ของ Quartz แตกต่างจาก cron ของ Unix เล็กน้อย โดยวางวินาทีไว้ช่องแรก

// Quartz cron format: sec min hour dom month dow [year]

"0 0 8 * * ?"     // Every day at 8:00 AM
"0 0/30 9-17 * * ?" // Every 30 min, 9 AM - 5 PM weekdays
"0 0 0 1 * ?"     // First day of every month at midnight
"0 0 6 ? * MON-FRI" // Every weekday at 6 AM
"0 0/5 * * * ?"   // Every 5 minutes

// Tip: use cronmaker.com or crontab.guru to build expressions

ตัวกระตุ้นแบบง่าย

สำหรับกำหนดการตามช่วงเวลาที่ไม่ซับซ้อนเท่า cron ให้ใช้ตัวกระตุ้นแบบง่ายร่วมกับ WithSimpleSchedule

q.AddTrigger(opts => opts
    .ForJob(jobKey)
    .WithIdentity("CleanupTrigger")
    .StartNow()
    .WithSimpleSchedule(s => s
        .WithIntervalInHours(1)
        .RepeatForever())
);

// Or a one-shot trigger:
q.AddTrigger(opts => opts
    .ForJob(jobKey)
    .WithIdentity("OneShot")
    .StartAt(DateTimeOffset.UtcNow.AddMinutes(5)));

แผนผังข้อมูลของงาน

ส่งพารามิเตอร์ขณะทำงานไปยังงานผ่าน JobDataMap เข้าถึงพารามิเตอร์เหล่านี้ภายใน Execute ผ่านทาง context.JobDetail.JobDataMap

q.AddJob<EmailJob>(opts => opts
    .WithIdentity("EmailJob")
    .UsingJobData("to", "admin@example.com")
    .UsingJobData("subject", "Daily Digest"));

// Inside the job:
public async Task Execute(IJobExecutionContext context)
{
    var to      = context.JobDetail.JobDataMap.GetString("to");
    var subject = context.JobDetail.JobDataMap.GetString("subject");
    await _mailer.SendAsync(to!, subject!, "body");
}

DisallowConcurrentExecution

[DisallowConcurrentExecution] ป้องกันไม่ให้อินสแตนซ์ใหม่ของงานเริ่มทำงานขณะที่อินสแตนซ์ก่อนหน้ายังทำงานอยู่ เหมาะอย่างยิ่งสำหรับงานที่เข้าถึงทรัพยากรร่วมกัน

[DisallowConcurrentExecution]
public class InventorySyncJob : IJob
{
    // If a sync takes > 1 minute and triggers every minute,
    // the next trigger is delayed until this one completes

    public async Task Execute(IJobExecutionContext context)
    {
        await SyncInventoryAsync(context.CancellationToken);
    }
}

// Without [DisallowConcurrentExecution], multiple instances
// could run in parallel, causing data conflicts.

การจัดการข้อยกเว้นและการลองใหม่

ห่อโค้ดของงานด้วย try/catch โยน JobExecutionException เพื่อแจ้งให้ Quartz เรียกใช้งานซ้ำทันทีหรือหลังจากมีความล่าช้า

public async Task Execute(IJobExecutionContext context)
{
    try
    {
        await ProcessAsync(context.CancellationToken);
    }
    catch (TransientException ex)
    {
        // Ask Quartz to retry immediately
        var jobException = new JobExecutionException(ex)
        {
            RefireImmediately = true
        };
        throw jobException;
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Job failed — not retrying");
        // Don't rethrow — job is done
    }
}

ตัวอย่างการใช้งานจริง: ตัวจัดกำหนดเวลาหลายงาน

การตั้งค่า Quartz สำหรับระบบจริงที่มีหลายงานตามกำหนดเวลาที่แตกต่างกัน โดยทุกงานใช้ DI สำหรับบริการต่าง ๆ

builder.Services.AddQuartz(q =>
{
    q.UseMicrosoftDependencyInjectionJobFactory();

    // Daily report at 8 AM
    var reportKey = new JobKey("DailyReport");
    q.AddJob<ReportGeneratorJob>(o => o.WithIdentity(reportKey));
    q.AddTrigger(o => o.ForJob(reportKey)
        .WithCronSchedule("0 0 8 * * ?"));

    // Inventory sync every 15 minutes
    var syncKey = new JobKey("InventorySync");
    q.AddJob<InventorySyncJob>(o => o.WithIdentity(syncKey));
    q.AddTrigger(o => o.ForJob(syncKey)
        .WithSimpleSchedule(s => s
            .WithIntervalInMinutes(15)
            .RepeatForever()));

    // Cache cleanup every night at 2 AM
    var cacheKey = new JobKey("CacheCleanup");
    q.AddJob<CacheCleanupJob>(o => o.WithIdentity(cacheKey));
    q.AddTrigger(o => o.ForJob(cacheKey)
        .WithCronSchedule("0 0 2 * * ?"));
});

ตรวจสอบความเข้าใจ

แอตทริบิวต์ [DisallowConcurrentExecution] ทำหน้าที่อะไรกับงาน Quartz.NET

สรุป: งานที่กำหนดเวลาด้วย Quartz.NET

ประเด็นสำคัญ:

  • Quartz.NET: ตัวจัดกำหนดเวลาระดับพร้อมใช้งานจริงที่รองรับ cron การคงอยู่ของงาน และการทำงานเป็นคลัสเตอร์
  • กำหนดงานด้วยการใช้งาน IJob พร้อมเมธอด Execute
  • ลงทะเบียนด้วย AddQuartz + AddQuartzHostedService โดยงานรองรับ DI
  • รูปแบบ cron: วินาที นาที ชั่วโมง วันของเดือน เดือน วันของสัปดาห์ — โปรดสังเกตว่าวินาทีอยู่ก่อน
  • [DisallowConcurrentExecution]: รอให้การทำงานปัจจุบันเสร็จสิ้นก่อนเรียกใช้งานซ้ำ
  • ใช้ JobDataMap เพื่อส่งพารามิเตอร์ขณะทำงานไปยังงาน

คำถามที่พบบ่อย

บทเรียน “งานตามกำหนดเวลาด้วย Quartz.NET” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “งานตามกำหนดเวลาด้วย Quartz.NET” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “งานตามกำหนดเวลาด้วย Quartz.NET”

กำหนดงานและทริกเกอร์ด้วย Quartz.NET ใช้นิพจน์ cron และผสานการทำงานกับ DI ของ ASP.NET Core คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “งานตามกำหนดเวลาด้วย Quartz.NET” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม

ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. IHostedService และ BackgroundService
  2. โครงการ Worker Service
  3. งานตามช่วงเวลาและตัวจับเวลา
  4. งานตามกำหนดเวลาด้วย Quartz.NET
← กลับไปที่ C# Academy