Quartz是Java平台的一個開源的作業調度框架。Quartz.net是從java版本移植到.net版本的。.net項目使用Quartz來執行批處理等定時任務非常方便。
(1)從nuget上可以安裝Quartz.net
(2)quartz配置:
<configSections> <section name="quartz" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections> <quartz> <add key="quartz.scheduler.instanceName" value="ExampleDefaultQuartzScheduler"/> <add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz"/> <add key="quartz.threadPool.threadCount" value="10"/> <add key="quartz.threadPool.threadPriority" value="2"/> <add key="quartz.jobStore.misfireThreshold" value="60000"/> <add key="quartz.jobStore.type" value="Quartz.Simpl.RAMJobStore, Quartz"/> </quartz> <appSettings> <!--cronexpression表達式:從每分鍾的第2秒開始,每間隔5秒執行--> <add key="cronExpr" value="2/5 * * * * ?"/> </appSettings>
(3)創建一個普通類,實現Quartz.IJob接口
接口很簡單,只有一個Execute()方法(跟java里一樣),在這個方法里寫你要做的處理邏輯。
public class MyJob : Quartz.IJob { public void Execute(Quartz.IJobExecutionContext context) { // 你的處理邏輯,也就是“工作” Console.WriteLine(DateTime.Now); } }
(4)啟動工作調度
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
class Program { static void Main(string[] args) { // Initializes a new instance of the Quartz.Impl.StdSchedulerFactory class. ISchedulerFactory sf = new Quartz.Impl.StdSchedulerFactory(); // Returns a client-usable handle to a Quartz.IScheduler. IScheduler sched = sf.GetScheduler(); // 定義一個Job(即你的處理邏輯,也就是“工作”) IJobDetail job = new JobDetailImpl("job1", "group1", typeof(MyJob)); // 定義觸發器(讀取AppSettings) string cronExpr = ConfigurationManager.AppSettings["cronExpr"]; ITrigger trigger = new CronTriggerImpl("trigger1", "group1", "job1", "group1", cronExpr); // 將給定的Job添加到調度器里 sched.AddJob(job, true, true); // 為Job指派觸發器 sched.ScheduleJob(trigger); // 啟動調度器線程 sched.Start(); Console.Read(); } }
我這里是一個控制台程序。對於web程序或服務程序,當Application_End的時候,需要調用Scheduler的Shutdown()方法來關閉Quartz的工作。
注意IScheduler有兩個重載的AddJob方法:
namespace Quartz { public interface IScheduler { // // 摘要: // Add the given Quartz.IJob to the Scheduler - with no associated Quartz.ITrigger. // The Quartz.IJob will be 'dormant' until it is scheduled with a Quartz.ITrigger, // or Quartz.IScheduler.TriggerJob(Quartz.JobKey) is called for it. // // 備注: // The Quartz.IJob must by definition be 'durable', if it is not, SchedulerException // will be thrown. void AddJob(IJobDetail jobDetail, bool replace); // // 摘要: // Add the given Quartz.IJob to the Scheduler - with no associated Quartz.ITrigger. // The Quartz.IJob will be 'dormant' until it is scheduled with a Quartz.ITrigger, // or Quartz.IScheduler.TriggerJob(Quartz.JobKey) is called for it. // // 備注: // With the storeNonDurableWhileAwaitingScheduling parameter set to true, a // non-durable job can be stored. Once it is scheduled, it will resume normal // non-durable behavior (i.e. be deleted once there are no remaining associated // triggers). void AddJob(IJobDetail jobDetail, bool replace, bool storeNonDurableWhileAwaitingScheduling); } }
上面的AddJob要調用void AddJob(IJobDetail jobDetail, bool replace, bool storeNonDurableWhileAwaitingScheduling);把storeNonDurableWhileAwaitingScheduling參數設置為true。否則會拋出SchedulerException異常:
未處理Quartz.SchedulerException HResult=-2146233088 Message=Jobs added with no trigger must be durable. Source=Quartz StackTrace: 在 Quartz.Core.QuartzScheduler.AddJob(IJobDetail jobDetail, Boolean replace, Boolean storeNonDurableWhileAwaitingScheduling) 位置 c:\Program Files (x86)\Jenkins\workspace\Quartz.NET\src\Quartz\Core\QuartzScheduler.cs:行號 788 在 Quartz.Core.QuartzScheduler.AddJob(IJobDetail jobDetail, Boolean replace) 位置 c:\Program Files (x86)\Jenkins\workspace\Quartz.NET\src\Quartz\Core\QuartzScheduler.cs:行號 779 在 Quartz.Impl.StdScheduler.AddJob(IJobDetail jobDetail, Boolean replace) 位置 c:\Program Files (x86)\Jenkins\workspace\Quartz.NET\src\Quartz\Impl\StdScheduler.cs:行號 286 在 UnitTest.Program.Main(String[] args) 位置 d:\SourceProject\infrastructure.sms\trunk\UnitTest\Program.cs:行號 36 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 在 System.Threading.ThreadHelper.ThreadStart_Context(Object state) 在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 在 System.Threading.ThreadHelper.ThreadStart()
(5)接下來,就可以允許程序,查看效果了。
關於quartz的CronExpression表達式:
常用示例:
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分每分觸發
0 0/5 14 * * ? 每天下午的 2點到2點59分(整點開始,每隔5分觸發)
0 0/5 14,18 * * ? 每天下午的 2點到2點59分、18點到18點59分(整點開始,每隔5分觸發)
0 0-5 14 * * ? 每天下午的 2點到2點05分每分觸發
0 10,44 14 ? 3 WED 3月份每周三下午的 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 ? * 6L 每月最后一周的星期五的10點15分觸發
0 15 10 ? * 6L 2002-2005 從2002年到2005年每月最后一周的星期五的10點15分觸發
0 15 10 ? * 6#3 每月的第三周的星期五開始觸發
0 0 12 1/5 * ? 每月的第一個中午開始每隔5天觸發一次
0 11 11 11 11 ? 每年的11月11號 11點11分觸發(光棍節)