# Quartz NET 排程作業套件 ###### tags: `C#` `Core` ## 介紹 直接引用官方網站的一句話簡單明瞭 **Open-source job scheduling system for .NET** ## 目錄 [TOC] # 一、前言 專案上很常使用此套件來執行排程,架構好之後就很少回去調整之後使用又要在看一輪資料,為了自己的金魚腦整理一下自己的筆記下來。 # 二、觀念建立 在實作之前我們先來建立觀念 > 下面的資料官方文件也有,在這邊簡單翻譯一下 * IScheduler - 主要和排程互動的API介面。 * IJob - 繼承此介面用來時做想執行的程序,此程序會被`Scheduler`執行。 * IJobDetail - 用來明確定義`Job`。 * ITrigger - 定義觸發`Job`的邏輯,不同的`Job`可以和不同的`Trigger`做關聯。 和三個Builder`JobBuilder`、`TriggerBuilder`、`SchedulerBuilder`功能就如命名規則 用程式碼來解釋的話如下 ```csharp= // 定義 Job 服務並且綁定 HelloJob class IJobDetail job = JobBuilder.Create<HelloJob>() .WithIdentity("myJob", "group1") // name "myJob", group "group1" .Build(); // 定義 Trigger 邏輯,啟動觸發之後每隔40秒執行一次且不停止 ITrigger trigger = TriggerBuilder.Create() .WithIdentity("myTrigger", "group1") .StartNow() .WithSimpleSchedule(x => x .WithIntervalInSeconds(40) .RepeatForever()) .Build(); // 告知 quartz Schedule 長得如何 await sched.scheduleJob(job, trigger); ``` 這邊是服務建立的基本概念,其服務的建立方式還有很多種,但不會脫離上面的基本架構。 # 三、使用介紹 此套件提供很多作法來去實作,這邊的作法是要執行比較用的方法**Hosted Services**[官方教學](https://www.quartz-scheduler.net/documentation/quartz-3.x/packages/hosted-services-integration.html#installation)也有很詳細的作法,不過還是紀錄程自己的筆記吧。 > Hosted Services 和 Microsoft Dependency Injection 兩個方法其實差不多 > 倒頭來還是使用`IServiceCollection`下去操作 ## 專案建立 這邊是建立一個新個worker專案來當範例(依據個人需求再調整),接著要安裝以下兩個套件 [Quartz.AspNetCore](https://www.nuget.org/packages/Quartz.AspNetCore) [Quartz.Extensions.Hosting](https://www.nuget.org/packages/Quartz.Extensions.Hosting) 完成後專案檔會出現對應套件和版本,這邊就不在贅述 ![](https://i.imgur.com/n9vEbZG.png) ## 服務建立 我們來建立一個固定印出時間的排程,首先實作`IJob`介面裡面主要邏輯為列印出時間,此外會Job可以使用以下屬性 * DisallowConcurrentExecution - 程序不允許同時執行 * PersistJobDataAfterExecution - 此參數較少使用,透過解釋感覺像是排程的值得控制。 ```csharp= using Quartz; [DisallowConcurrentExecution] public class TimeJob : IJob { private readonly ILogger<TimeJob> _logger; public TimeJob(ILogger<TimeJob> logger) { this._logger = logger; } public Task Execute(IJobExecutionContext context) { _logger.LogInformation(DateTime.Now.ToString()); return Task.CompletedTask; } } ``` 這邊我們在Host啟動之前先去設定好運行方式以及加入排程,相關解釋就看程式碼內部的註解 ```csharp= using Quartz; IHost host = CreateHost(args); await host.RunAsync(); IHost CreateHost(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddQuartz(q => { // 這邊寫上排程的相關設定 或 排程建立 // 可以使服務注入用 scoped 方式注入 q.UseMicrosoftDependencyInjectionJobFactory(); // 這邊都是預設值 q.UseSimpleTypeLoader(); q.UseInMemoryStore(); q.UseDefaultThreadPool(tp => { // 併發數量 tp.MaxConcurrency = 10; }); // 一秒後執行之後每秒執行 q.ScheduleJob<TimeJob>(trigger => trigger .WithIdentity("TimeJob") .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(1))) .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).RepeatForever()) ); }); // Host 服務建立 services.AddQuartzHostedService(options => { // 主程式關閉時,會確保當前任務已經完成 options.WaitForJobsToComplete = true; }); }) .Build(); ``` 執行結果如下 ![](https://i.imgur.com/XdbVL5h.png) # 四、UI控制 網路上有提供一些方法讓我們可以藉由UI控制和觀測排程,這邊提供網路上找到的兩種方法,因為本身沒有需求所以這一個區塊就不實作了 [CrystalQuartz](https://www.nuget.org/packages/CrystalQuartz.AspNetCore/6.11.0.3-beta) [[ASP.NET Core] 將 Quartz.Net 排程作業 Host 於 ASP.NET Core 網站中,並以 SignalR 實現 Dashboard 頁面](https://dotblogs.com.tw/wasichris/2020/12/16/172524) # 結論 整理來說算是非常簡單套件,不過其實該套件還有提很多不同控制排程的方式,但如果只要簡單讓它在背後執行就直接照範例執行吧。 最後附[Githib](https://github.com/franksu129/QuartzNet-Sample) <br/> --- 相關參考來源: [Quartz.NET](https://www.quartz-scheduler.net/) [CrystalQuartz](https://github.com/guryanovev/CrystalQuartz) <style> code > span{ color: red;} </style>