Quartz.NET是一個強大、開源、輕量的作業調度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改寫,可用於winform和asp.net應用中。它靈活而不複雜。你能夠用它來為執行一個作業而創建簡單的或複雜的作業調度。它有很多特征,如:資料庫支持,集群,插件,... ...
一、概述
Quartz.NET是一個強大、開源、輕量的作業調度框架,是 OpenSymphony 的 Quartz API 的.NET移植,用C#改寫,可用於winform和asp.net應用中。它靈活而不複雜。你能夠用它來為執行一個作業而創建簡單的或複雜的作業調度。它有很多特征,如:資料庫支持,集群,插件,支持cron-like表達式等等。
通俗說它的功能是:比如說我想每天晚上2點讓程式或網站執行某些代碼,或者每隔5秒種我想查看是否有新的任務要處理等。
官網:http://www.quartz-scheduler.net/
源碼:https://github.com/quartznet/quartznet
示例:http://www.quartz-scheduler.net/documentation/quartz-2.x/quick-start.html
其實Quartz是一個完全由java編寫的開源作業調度框架,Quartz是OpenSymphony開源組織在Job scheduling領域又一個開源項目,它可以與J2EE與J2SE應用程式相結合也可以單獨使用。Quartz可以用來創建簡單或為運行十個,百個,甚至是好幾萬個Jobs這樣複雜的程式。而Quartz.Net與NPOI一樣是一個DoNet平臺下的對應版本。如果您使用Java直接訪問這裡就好了http://www.quartz-scheduler.org/
二、依賴框架
引入框架的方法非常簡單你可以直接用nuget管理包,也可以在項目中添加引用,這裡主要介紹前者。
2.1 安裝Nuget
新版本的Visual Studio預設情況是安裝了Nuget的,如Visual Studio2015,但如果沒有安裝,打開VS菜單“工具”->"擴展與更新"
在擴展與更新中搜索“nuget”,可以新安裝或卸載後升級:
2.2 修改Nuget鏡像
為解決國內訪問NuGet伺服器速度不穩定的問題建議你最好選擇一些鏡像伺服器,這樣可以加速下載。
在Visual Studio中的添加方法是:打開“工具”->“選項”菜單
在左側菜單中找到“NuGet包管理器”
點擊右上角的加號,添加兩個鏡像,這些地址可以上網搜索,我使用的是如下兩個:
https://nuget.cnblogs.com/v3/index.json
http://api.nuget.org/v3/index.json
設置一下順序就OK了。
2.3 使用nuget安裝Quartz.NET
點擊“工具”->"NuGet包管理器"->“程式包管理器控制台”
輸入安裝包的命令:
Install-Package Quartz
安裝結果如下:
此時包管理器中就下載了需要的程式集與相關文件,程式中也添加了引用。
三、框架應用
3.1 定義要執行的任務
定義一個類,實現Quartz.IJob介面,實現方法Execute,TimeJob.cs文件的代碼如下:
1 using System; 2 using System.Threading.Tasks; 3 using Quartz; 4 using System.IO; 5 6 namespace QuartzDoNetDemo 7 { 8 /// <summary> 9 /// 文件記時任務 10 /// </summary> 11 public class TimeJob : IJob 12 { 13 /// <summary> 14 /// 文件記時任務 15 /// </summary> 16 /// <param name="context"></param> 17 /// <returns></returns> 18 Task IJob.Execute(IJobExecutionContext context) 19 { 20 21 //方式一 22 //Environment:提供有關當前環境和平臺的信息以及操作它們的方法 23 //File.AppendAllText(@"d:\Quartz.txt", DateTime.Now + Environment.NewLine); 24 //return Task.Run(() => Console.WriteLine(DateTime.Now)); 25 26 //方式二 27 File.AppendAllText(@"d:\Quartz.txt", DateTime.Now + Environment.NewLine); 28 Console.WriteLine(DateTime.Now); 29 return Task.FromResult(true); 30 } 31 } 32 }View Code
3.2 創建一個調度器
調度器負責管理與控制任務的執行:
1 //創建調度器工廠 2 ISchedulerFactory factory = new StdSchedulerFactory(); 3 4 //創建調度器 5 IScheduler scheduler = await factory.GetScheduler();
3.3 創建一個任務對象
這個任務對象就是我們將要執行的工作,job1是名稱,group1是組名。
IJobDetail job = JobBuilder.Create<TimeJob>().WithIdentity("myJob1", "group1").Build();
3.4 創建一個觸發器
觸發器定義了什麼時間任務開始或每隔多久執行一次.
1 //創建一個觸發器:WithSimpleSchedule(a => a.WithIntervalInSeconds(10).RepeatForever()) 2 ITrigger trigger = TriggerBuilder.Create().WithIdentity("myTrigger1", "group1").StartNow().WithCronSchedule("0/10 * * * * ?").Build();
3.5 將任務與觸發器添加到調度器中並執行
1 //將任務和觸發器添加到調度器里 2 await scheduler.ScheduleJob(job, trigger); 3 4 //開始執行 5 await scheduler.Start();
3.6 Quartz的cron表達式
cron表達式就是用於設定時間的一個字元串,在前面的代碼中我們就用到了,如下所示:
1 //創建一個觸發器 2 ITrigger trigger = TriggerBuilder.Create() 3 .WithIdentity("myTrigger1", "group1") 4 .StartNow() 5 .WithCronSchedule("0/10 * * * * ?") //每10秒執行一次 6 .Build();
官方英文介紹:http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/crontrigger.html
cron expressions 整體上還是非常容易理解的,只有一點需要註意:"?"號的用法,看下文可以知道“?”可以用在 day of month 和 day of week中,他主要是為瞭解決如下場景,如:每月的1號的每小時的31分鐘,正確的表達式是:* 31 * 1 * ?,而不能是:* 31 * 1 * *,因為這樣代表每周的任意一天。
/* 由7段構成:秒 分 時 日 月 星期 年(可選) "-" :表示範圍 MON-WED表示星期一到星期三 "," :表示列舉 MON,WEB表示星期一和星期三 "*" :表是“每”,每月,每天,每周,每年等 "/" :表示增量:0/15(處於分鐘段裡面) 每15分鐘,在0分以後開始,3/20 每20分鐘,從3分鐘以後開始 "?" :只能出現在日,星期段裡面,表示不指定具體的值 "L" :只能出現在日,星期段裡面,是Last的縮寫,一個月的最後一天,一個星期的最後一天(星期六) "W" :表示工作日,距離給定值最近的工作日 "#" :表示一個月的第幾個星期幾,例如:"6#3"表示每個月的第三個星期五(1=SUN...6=FRI,7=SAT) 如果Minutes的數值是 '0/15' ,表示從0開始每15分鐘執行 如果Minutes的數值是 '3/20' ,表示從3開始每20分鐘執行,也就是‘3/23/43’ */
官方示例:
表達式 |
解釋 |
0 0 12 * * ? |
每天中午12點觸發 |
0 15 10 ? * * |
每天上午10:15觸發 |
0 15 10 * * ? |
每天上午10:15觸發 |
0 15 10 * * ? * |
每天上午10:15觸發 |
0 15 10 * * ? 2005 |
2005年的每天上午10:15觸發 |
0 * 14 * * ? |
在每天下午2點到下午2:59期間的每1分鐘觸發 |
0 0/5 14 * * ? |
在每天下午2點到下午2:55期間的每5分鐘觸發 |
0 0/5 14,18 * * ? |
在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發 |
0 0-5 14 * * ? |
在每天下午2點到下午2:05期間的每1分鐘觸發 |
0 10,44 14 ? 3 WED |
每年三月的星期三的下午2:10和2:44觸發 |
0 15 10 ? * MON-FRI |
周一至周五的上午10:15觸發 |
0 15 10 15 * ? |
每月15日上午10:15觸發 |
0 15 10 L * ? |
每月最後一日的上午10:15觸發 |
0 15 10 L-2 * ? |
每個月的第二天到最後一天的上午10:15觸發 |
0 15 10 ? * 6L |
每月的最後一個星期五上午10:15觸發 |
0 15 10 ? * 6L |
每個月最後一個星期五上午10時15分觸發 |
0 15 10 ? * 6L 2002-2005 |
2002年至2005年的每月的最後一個星期五上午10:15觸發 |
0 15 10 ? * 6#3 |
每月的第三個星期五上午10:15觸發 |
0 0 12 1/5 * ? |
每月每隔5天下午12點(中午)觸發, 從每月的第一天開始 |
0 11 11 11 11 ? |
每11月11日上午11時11分觸發 |
參考資料: