天天看點

Quartz.Net實作定時排程學習總結

定時排程可以了解為定時執行某個方法或邏輯代碼,Timer也可以實作類似的功能。Quartz就是啟動定時任務的架構,直接在項目引用後就可以調用。

準備工作:

項目安裝Quartz

代碼實作:

1.聲明Scheduler(作業排程池)

2.聲明JobDetail

3.聲明Trigger

4.将JobDetail和Trigger添加到作業排程池中

下面是詳細的步驟:

項目引用Quartz,使用NuGet包管理器安裝,我安裝的Quartz是3.0.7版本(不同的版本,對應的api調用方式不一樣2.x和3.x差別挺大),對應的.NETFramework版本要求至少為4.5.2。

Quartz.Net實作定時排程學習總結

代碼實作部分:

1.Scheduler 作業排程器

StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
await scheduler.Start();
           

2.JobBuilder 根據設定,生成一個詳細作業資訊(JobDetail)。(也就是具體要執行的邏輯代碼)

IJobDetail jobDetail1 = JobBuilder.Create<JobDemo>().WithIdentity("testjob", "group1").WithDescription("我是testjob").Build();
jobDetail1.JobDataMap.Add("name", "張三");
jobDetail1.JobDataMap.Add("age", "20");
           

3.TriggerBuilder   根據規則,生産對應的Trigger。(時間政策,什麼時候執行,執行間隔,執行次數等等)

//程式啟動2秒後執行,間隔3秒執行一次,一直執行
ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(2)))
                  .WithCronSchedule("0/3 * * * * ?").WithDescription("我是testjob的觸發器").Build();
           

4.加入作業排程池中

await scheduler.ScheduleJob(jobDetail1, trigger);
           

完整代碼如下:

public async static Task Init()
        {
            try
            {
                Console.WriteLine("初始化scheduler.....");

                //1.Scheduler 作業排程器
                StdSchedulerFactory factory = new StdSchedulerFactory();
                IScheduler scheduler = await factory.GetScheduler();
                await scheduler.Start();

                //2.JobBuilder 根據設定,生成一個詳細作業資訊(JobDetail)。
                IJobDetail jobDetail1 = JobBuilder.Create<JobDemo>().WithIdentity("testjob", "group1").WithDescription("我是testjob").Build();
                jobDetail1.JobDataMap.Add("name", "張三");
                jobDetail1.JobDataMap.Add("age", "20");


                //3.TriggerBuilder   根據規則,生産對應的Trigger
                //程式啟動2秒後執行,間隔3秒執行一次,一直執行
                ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(2)))
                  .WithCronSchedule("0/3 * * * * ?").WithDescription("我是testjob的觸發器").Build();


                //4.加入作業排程池中
                await scheduler.ScheduleJob(jobDetail1, trigger);


                Console.WriteLine("作業添加完成.....");
            }
            catch (Exception)
            {
                throw;
            }

        }
           

其中自定義邏輯是寫在第二步的JobDemo類中,代碼如下:

//IJob 作業接口,繼承并實作Execute, 編寫執行的具體作業邏輯。
    public class JobDemo : IJob
    {
        public async Task Execute(IJobExecutionContext context)
        {
            try
            {
                await Task.Run(() =>
                {
                    Console.WriteLine();

                    JobDataMap map = context.JobDetail.JobDataMap;
                    Console.WriteLine(map.Get("name"));
                    Console.WriteLine(map.Get("age"));
                    Console.WriteLine(DateTime.Now.ToString("r"));

                    Console.WriteLine();
                });
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
           

 以上代碼實作的邏輯是程式啟動2秒後開始列印在第二步中為jobDetail1添加的參數資訊。每隔3秒列印一次,隻要程式不停止,就一直執行。

如下所示:

Quartz.Net實作定時排程學習總結

用法的補充和擴充:

在第三步,建立Trigger,是為了控制程式運作的周期,運作次數等等

上面代碼示例中使用的是Cron表達式,詳細用法參考:https://www.cnblogs.com/sunjie9606/archive/2012/03/15/2397626.html

同時網上也有生成Cron表達式的工具,可以根據選擇的時間自動生成表達式:https://cron.qqe2.com/

除了Cron表達式外,還有另外的寫法來控制程式運作的周期,比如Simple模式。代碼如下:

//程式啟動立刻執行,間隔一秒執行一次,一共執行2+1次
ITrigger trigger = TriggerBuilder.Create().WithIdentity("testtrigger", "group1").StartNow()
                    .WithSimpleSchedule(x => x.WithIntervalInSeconds(1).WithRepeatCount(2)).WithDescription("我是testjob的觸發器").Build();
           

 這段代碼可以替換上面執行個體中第三部分的代碼,實作的邏輯是程式啟動後立刻執行任務,每隔一秒鐘執行一次,一共重複2次,加上剛開始執行的一次,一共會執行3次。

StartNow(),立即執行作業任務

WithIntervalInSeconds(1),一秒執行一次

WithRepeatCount(2),重複執行兩次,這裡也可以用RepeatForever(),表示永遠執行下去,不限制執行次數。

還有很多其他的api可以通過自行檢視,檢視方法如下:

Quartz.Net實作定時排程學習總結

關于監聽Listener

Quartz的監聽器用于當任務排程中所關注事件的發生時,能夠及時擷取這一事件的通知。類似于任務執行過程中郵件、短信類的提醒。Quartz監聽器主要有SchedulerListener、 TriggerListener、JobListener三種,分别表示排程器、觸發器、任務對應的監聽器。

三者使用方法類似。下面以TriggerListener為例,寫一個類說明用法:

MyTriggerListener類:

public class MyTriggerListener : ITriggerListener
    {
        public string Name => "MyTriggerListener";

        public async Task TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("job完成時調用");
                Console.WriteLine();

            });
        }

        public async Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("job執行時調用");
            });
        }

        public async Task TriggerMisfired(ITrigger trigger, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Run(() =>
            {
                Console.WriteLine("錯過觸發時調用(例:線程不夠用的情況下)");
            });
        }

        public async Task<bool> VetoJobExecution(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken))
        {
            //Trigger觸發後,job執行時調用本方法。true即否決,job後面不執行。
            await Task.Run(() =>
            {
                Console.WriteLine("Trigger觸發後,job執行時調用本方法。");
            });
            return false;
        }
    }
           

自定義的MyTriggerListener實作後,需要添加監聽器到指定的trigger,如圖所示:

Quartz.Net實作定時排程學習總結

代碼: 

scheduler.ListenerManager.AddTriggerListener(new MyTriggerListener());//添加TriggerListener
           

添加完成後,再次啟動項目,可以看到在控制台列印了相關資訊:

Quartz.Net實作定時排程學習總結

其他兩個監聽器用法類似。 

關于監聽器可以參考下面連結,雖然是java版本的,但是很多東西是相同的,畢竟.Net的Quartz是由java版本變化而來。

https://www.cnblogs.com/mengrennwpu/p/7191229.html

繼續閱讀