公司內部有使用 Quartz.NET 來排程管理,了解並簡易筆記基礎用法,該筆記為 Quartz.NET 3.3.3 版本
常見三個功能,分別為 Job、Trigger 和 Scheduler
- Job 必須實作 IJob Interface,只有一個 Execute 方法
- Trigger:設定 Job 被執行的時間、頻率,有 SimpleTrigger 和 CronTrigger 兩種
- Scheduler:對應 Job 和 Trigger,基本上大多以 StdSchedulerFactory 為主
Job:單純輸出時間,該 Job 有套用 DisallowConcurrentExecutionAttribute,下面為官方說明
An attribute that marks a IJob class as one that must not have multiple instances executed concurrently (where instance is based-upon a IJobDetail definition - or in other words based upon a JobKey).
簡單說就是一次只能建立一個 Job 出來跑就是啦,單純筆記該重點,不會有明顯效果可以觀察喔
using Quartz;
using System;
using System.Threading.Tasks;
namespace QuartzSample
{
[DisallowConcurrentExecution]
public class HelloQuartzJob : IJob
{
public Task Execute(IJobExecutionContext context)
{
return Task.Run(() =>
{
Console.WriteLine($"Hello Quartz.Net - {DateTime.Now}");
});
}
}
}
Job:參數傳遞,紀錄兩種參數傳遞方式
using Quartz;
using System;
using System.Threading.Tasks;
namespace QuartzSample
{
public class SayHelloJob : IJob
{
// 參數直接注入 UserName
public string UserName { get; set; }
public Task Execute(IJobExecutionContext context)
{
// 透過 context 抓取參數
JobKey key = context.JobDetail.Key;
JobDataMap dataMap = context.JobDetail.JobDataMap;
string UserNameFromContext = dataMap.GetString("UserNameFromContext");
return Task.Run(() =>
{
Console.WriteLine($"兩位好:{UserName} - {UserNameFromContext} - {DateTime.Now}");
});
}
}
}
Quartz.NET 執行 Code
using Quartz;
using Quartz.Impl;
using System;
using System.Threading.Tasks;
namespace QuartzSample
{
internal class Program
{
static async Task Main(string[] args)
{
// 取得 Scheduler 並啟動
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
// 假如 Scheduler 沒有啟動的話,Trigger 是不會開始動的喔
await scheduler.Start();
// 定義 Job
IJobDetail job = JobBuilder.Create<HelloQuartzJob>()
.Build();
IJobDetail job2 = JobBuilder.Create<SayHelloJob>()
.UsingJobData(nameof(SayHelloJob.UserName), "Terry")
.UsingJobData("UserNameFromContext", "Vivian")
.Build();
// 定義 Trigger
ITrigger trigger = TriggerBuilder.Create()
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(1) // 每一秒觸發一次
.RepeatForever())
.Build();
ITrigger trigger2 = TriggerBuilder.Create()
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(3) // 每三秒觸發一次
.RepeatForever())
.Build();
// 對應 Job 和 Trigger
await scheduler.ScheduleJob(job, trigger);
await scheduler.ScheduleJob(job2, trigger2);
// Main Thread 結束後,全部的 Worker Thread 就結束了,會看不到輸出結果,
// 所以故意在這邊停止 10 秒
await Task.Delay(TimeSpan.FromSeconds(10));
}
}
}