最近公司的做的項目中涉及到配置任務地址然后按照配置去目標地址提取相關的數據,所以今天上午在Internet上查看有關定時任務(調度任務)的相關信息,篩選半天然后查找到Quartz.net。
Quartz.net概述:
Quartz.net是一個開源的作業調度框架,非常適合在平時的工作中,定時輪詢數據庫同步,定時郵件通知,定時處理數據等。 Quartz.NET允 許開發人員根據時間間隔(或天)來調度作業。它實現了作業和觸發器的多對多關系,還能把多個作業與不同的觸發器關聯。整合了 Quartz.NET的應用程序可以重用來自不同事件的作業,還可以為一個事件組合多個作業。
接下來說一下怎么安裝並使用:
1、首先建立一個名稱為“TestQuartz.net”的控制台項目,然后使用Nuget安裝Quartz.net,
由於項目中使用Mysql存儲調度框架的相關,所以需要下載Quartz.net能用的mysql .net數據驅動文件。
這個是對應關系:
- SqlServer-20 - SQL Server driver for .NET Framework 2.0
- OracleODP-20 - Oracle's Oracle Driver
- OracleODPManaged-1123-40 Oracle's managed driver for Oracle 11
- OracleODPManaged-1211-40 Oracle's managed driver for Oracle 12
- MySql-50 - MySQL Connector/.NET v. 5.0 (.NET 2.0)
- MySql-51 - MySQL Connector/:NET v. 5.1 (.NET 2.0)
- MySql-65 - MySQL Connector/:NET v. 6.5 (.NET 2.0)
- SQLite-10 - SQLite ADO.NET 2.0 Provider v. 1.0.56 (.NET 2.0)
- Firebird-201 - Firebird ADO.NET 2.0 Provider v. 2.0.1 (.NET 2.0)
- Firebird-210 - Firebird ADO.NET 2.0 Provider v. 2.1.0 (.NET 2.0)
- Npgsql-20 - PostgreSQL Npgsql
經過我反復測試MySql-65對應的驅動版本為:MySql.Data 6.5.4 版本。
這下在vs的“工具”菜單中找到“NUGET程序包管理器”並點擊“程序包管理控制台”
打開界面如下:
輸入 Install-Package MySql.Data -Version 6.5.4 並輸入回車安裝
2、在項目中新建DemoJob的類並繼承IJob接口(Ijob是Quartz.net的接口)
代碼如下:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using Quartz; 7 8 namespace TestQuartz.net 9 { 10 public class DemoJob : IJob 11 { 12 public void Execute(IJobExecutionContext context) 13 { 14 Console.WriteLine(string.Format("{0}執行一次", DateTime.Now)); 15 } 16 } 17 }
然后打開“Program.cs”的類文件,並編輯為如下代碼:
1 using System; 2 using System.Collections.Generic; 3 using System.Collections.Specialized; 4 using System.IO; 5 using System.Linq; 6 using System.Text; 7 using System.Threading; 8 using System.Threading.Tasks; 9 using Common.Logging; 10 using Quartz; 11 using Quartz.Impl; 12 13 namespace TestQuartz.net 14 { 15 public class Program 16 { 17 static void Main(string[] args) 18 { 19 IntQuartz(); 20 21 } 22 static void IntQuartz() 23 { 24 //1.首先創建一個作業調度池 25 var properties = new NameValueCollection(); 26 //存儲類型 27 properties["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX,Quartz"; 28 //表明前綴 29 properties["quartz.jobStore.tablePrefix"] = "QRTZ_"; 30 //驅動類型 31 properties["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.MySQLDelegate,Quartz"; 32 //數據源名稱 33 properties["quartz.jobStore.dataSource"] = "myDS"; 34 //連接字符串 35 properties["quartz.dataSource.myDS.connectionString"] = "Server=192.168.0.141;Database=test;Uid=root;Pwd=root"; 36 //版本 37 properties["quartz.dataSource.myDS.provider"] = "MySql-65"; 38 //最大鏈接數 39 //properties["quartz.dataSource.myDS.maxConnections"] = "5"; 40 // First we must get a reference to a scheduler 41 var schedulerFactory = new StdSchedulerFactory(properties); 42 var scheduler = schedulerFactory.GetScheduler(); 43 scheduler.Start(); 44 } 45 } 46 }
3、需要我們在MySql中建立數據庫和相應的數據表,不用發愁開源的項目中作者已為我們准備好了數據庫建立表的語句(打開此鏈接並復制數據庫語句執行)。
有啦數據庫后你會很興奮,直接寫t-sql操作數據庫多么便捷啊,並且所有的任務調度信息都一目了然,這里我要告訴你的事,你不需要直接寫sql語句,quart提供的類庫就能自動對數據庫進行填充,以完成對任務調度的管理操作。
4、操作事例:
添加一個任務並開始執行,代碼如下:

1 private static void Insert() 2 { 3 4 IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler(); 5 DateTime StarTime = DateTime.Now; 6 DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(StarTime, 1); 7 DateTime EndTime = DateTime.MaxValue.AddDays(-1); 8 DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(EndTime, 1); 9 IJobDetail job = JobBuilder.Create<DemoJob>() 10 .WithIdentity("j1", "g1") 11 .WithDescription("注釋") 12 .Build(); 13 ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create() 14 .StartAt(starRunTime)//指定運行時間 15 .EndAt(endRunTime)//指定結束時間 16 .WithIdentity("j1", "g1") 17 .WithCronSchedule("0/5 * * * * ?")//運行模式 每十秒鍾運行一次 18 .WithDescription("注釋") 19 .Build(); 20 scheduler.ScheduleJob(job, trigger); 21 scheduler.Start(); 22 }
其他:
IScheduler scheduler = StdSchedulerFactory.GetDefaultScheduler();
//刪除任務代碼 var trigger = new TriggerKey("j1", "g1"); scheduler.PauseTrigger(trigger);//停止觸發器 scheduler.UnscheduleJob(trigger); //移除觸發器 scheduler.DeleteJob(JobKey.Create(jobName, jobGroup));
//暫停單個任務
scheduler.PauseJob(JobKey.Create(jobName, jobGroup));
//暫停所有任務
scheduler.PauseAll();
//開啟指定任務
scheduler.ResumeJob(JobKey.Create(jobName, jobGroup));
//開啟所有任務
scheduler.ResumeAll();
//是否集群
properties["quartz.jobStore.clustered"] = "true";
properties["quartz.scheduler.instanceId"] = "AUTO";
5、Quartz的cron表達式
官方英文介紹地址: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)
官方實例
Expression | Meaning |
---|---|
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 * ? | Fire at 10:15am on the 2nd-to-last last day of every month |
0 15 10 ? * 6L | 每月的最后一個星期五上午10:15觸發 |
0 15 10 ? * 6L | Fire at 10:15am on the last Friday of every month |
0 15 10 ? * 6L 2002-2005 | 2002年至2005年的每月的最后一個星期五上午10:15觸發 |
0 15 10 ? * 6#3 | 每月的第三個星期五上午10:15觸發 |
0 0 12 1/5 * ? | Fire at 12pm (noon) every 5 days every month, starting on the first day of the month. |
0 11 11 11 11 ? | Fire every November 11th at 11:11am. |
至此事例項目已搭建完畢!
執行結果效果圖:
實測在開幾個客戶端下也不會都去執行。而是集中在某個客戶端下執行。
項目開源地址:https://github.com/quartznet/quartznet