天天看點

快速掌握Quartz.Net計劃任務排程架構,輕松實作定時任務

作者:小乖獸技術
快速掌握Quartz.Net計劃任務排程架構,輕松實作定時任務

Quartz.Net是一個開源的作業排程架構,可以用于管理計劃任務和定期執行。Quartz.Net提供了豐富的作業計劃選項,例如精确或模糊時間表達式、日期和時間限制等。Quartz.Net采用分布式架構,允許在多個計算機上運作任務。

  1. Quartz.Net架構設計

Quartz.Net的架構設計采用了經典的MVC(Model-View-Controller)模式,其中:

  • Model:表示應用程式中的資料和狀态。在Quartz.Net中,Model由Job和Trigger組成,并由Scheduler排程。
  • View:表示與使用者互動的部分。在Quartz.Net中,View由Scheduler架構提供的API和UI元件組成。
  • Controller:負責處理使用者輸入并更新Model和View。在Quartz.Net中,Controller由Scheduler控制器組成。
  1. Quartz.Net元件子產品

Quartz.Net包含以下元件子產品:

  • Scheduler:負責作業的排程和執行。Scheduler維護一個作業和觸發器的排程清單,并根據定義的條件選擇要排程的作業。
  • Job:表示要執行的作業。在Quartz.Net中,Job必須實作IJob接口。
  • Trigger:定義何時執行作業。在Quartz.Net中,有多種類型的觸發器可供選擇,例如簡單觸發器、Cron觸發器等。
  • JobDetail:表示作業的詳細資訊,包括執行作業所需的Job類及其名稱、描述和其他資料。
  • JobExecutionContext:在作業執行期間提供與應用程式和Quartz.Net架構互動所需的上下文資訊。
  • SchedulerFactory:用于建立Scheduler的工廠類。

在NetCore項目中內建Quartz.Net,可以通過以下步驟實作:

  1. 安裝Quartz.Net NuGet包

在Visual Studio的NuGet包管理器中搜尋安裝Quartz.Net包,或通過指令行安裝:dotnet add package Quartz。

  1. 建立作業類

依據項目需求建立對應的作業類,并實作IJob接口,例如:

public class MyJob : IJob
{
    public async Task Execute(IJobExecutionContext context)
    {
        await Console.Out.WriteLineAsync("Hello, Quartz.Net!");
    }
}           
  1. 配置Scheduler

在Startup.cs檔案中添加配置代碼,建立Scheduler,添加作業和觸發器:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IJobFactory, SingletonJobFactory>();
    services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
    services.AddSingleton(new JobSchedule(
        jobType: typeof(MyJob),
        cronExpression: "0/5 * * * * ?")); // 每5秒執行一次

    services.AddHostedService<QuartzHostedService>();
}

public class JobSchedule
{
    public Type JobType { get; }
    public string CronExpression { get; }

    public JobSchedule(Type jobType, string cronExpression)
    {
        JobType = jobType;
        CronExpression = cronExpression;
    }
}

public class SingletonJobFactory : IJobFactory
{
    private readonly IServiceProvider _serviceProvider;

    public SingletonJobFactory(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
    {
        return (IJob)_serviceProvider.GetService(bundle.JobDetail.JobType);
    }

    public void ReturnJob(IJob job)
    {
        // do nothing
    }
}

public class QuartzHostedService : IHostedService
{
    private readonly ISchedulerFactory _schedulerFactory;
    private readonly IJobFactory _jobFactory;
    private readonly IEnumerable<JobSchedule> _jobSchedules;

    public QuartzHostedService(
        ISchedulerFactory schedulerFactory, 
        IJobFactory jobFactory, 
        IEnumerable<JobSchedule> jobSchedules)
    {
        _schedulerFactory = schedulerFactory;
        _jobFactory = jobFactory;
        _jobSchedules = jobSchedules;
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
        scheduler.JobFactory = _jobFactory;

        foreach (var jobSchedule in _jobSchedules)
        {
            var jobDetail = JobBuilder.Create(jobSchedule.JobType).Build();

            var trigger = TriggerBuilder.Create()
                .WithCronSchedule(jobSchedule.CronExpression)
                .Build();

            await scheduler.ScheduleJob(jobDetail, trigger, cancellationToken);
        }

        await scheduler.Start(cancellationToken);
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        var scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
        await scheduler.Shutdown(cancellationToken);
    }
}
           
  1. 啟動和停止Scheduler

在Main函數中啟動排程程式:

public static async Task Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    await host.RunAsync();
}           

官方網站:https://www.quartz-scheduler.net/

官方文檔:https://www.quartz-scheduler.net/documentation/quartz-3.x/quick-start.html