前言
目前工作的專案如果有排程的需求(ex. 每天寄信、產生報表之類的)
大部分都是寫一隻程式然後放進Windows排程去執行,
如果是要產生報表資料則會用Mysql的event去跑。
日前收到了一包.net core 的source code,發現裡頭用了 Pomelo.AspNetCore.TimedJob 這個
可以定期執行任務的類別庫,才知道原來有這類型工具可以用啊
所以也想在目前手上的mvc.net 專案裡,增加相同的功能。
servey了一下,發現蠻人多推薦Quartz.NET這個套件,
立馬下載來用,果然是好物!
安裝
直接從NuGet直接下載安裝吧練習
主要需要實作3個相關的介面、類別建立排程器:IScheduler、StdSchedulerFactory
建立工作:IJobDetail、IJob:
建立觸發器:ITrigger、TriggerBuilder
1. 首先建立工作的類別
[DisallowConcurrentExecutionAttribute] public class Job_UpdateDeviceOnlineStatus : IJob { public Task Execute(IJobExecutionContext context) { return Task.Run(()=> { //update device online status }); } }工作內容是去檢查遠端device是否連線,先不多述
加上[DisallowConcurrentExecutionAttribute]
可以避免類別instance兩次,代表同時間只執行一次工作
2. 修改Global.asax,讓程式啟動的時候去加入排程工作
IScheduler scheduler = null; protected void Application_Start() { ...前略 StartSchedulerJon(); } protected void Application_End(Object sender, EventArgs e) { scheduler?.Shutdown(); } private async void StartSchedulerJon() { try { //建立排程器 var factory = new Quartz.Impl.StdSchedulerFactory(); scheduler = await factory.GetScheduler(); //建立工作 IJobDetail job = JobBuilder.Create<Job_UpdateDeviceOnlineStatus>() .WithIdentity("OnlineStatusUpdate") .Build(); //建立觸發器 ITrigger trigger = TriggerBuilder.Create() .WithSimpleSchedule(x => x .WithIntervalInMinutes(5) .RepeatForever()) .WithIdentity("trigger_OnlineStatusUpdate") .StartNow() .Build(); await scheduler.ScheduleJob(job, trigger); await scheduler.Start(); } catch(Exception ex) { //log Console.Error.Write(ex.Message); } }
trigger的時間有兩種表示方式,另一種是用CRON表示法
想將windows排程工作轉到.net應用程式裡,這種方式或許比較適合
ITrigger trigger2 = TriggerBuilder.Create() .WithCronSchedule("0 0/5 * * * * ") //每5分鐘跑一次 .WithIdentity("trigger_use_cron") .StartNow() .Build();
3. 修改Web.config
一些排程的參數放在config檔裡(ex. 時間、enable),可以比較彈性的去調整配置
這次先不做~懶
4.IIS 8.0 設定
*IIS需安裝"應用程式初始化"
*修改應用程式集區的進階設定,將「啟動模式」從預設的「OnDemand」改為「AlwaysRunning」
*修改網站的進階設定,把「預先載入已啟用」(Preload Enabled)由預設的 False 改為 True。
後記
簡單的實作就可以有強力大功能,
也要繼續觀查長期執行下來對Server有沒有什麼其它影響
其它詳細的內容請參考官網文件說明
參考
Huanlin學習筆記
官網