一個普通的 Job 實現以下:併發
public class Job1 : IJob { public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now + ": Job1" + m); } } public class Program { static void Main(string[] args) { var props = new NameValueCollection(); //使用簡單線程池 props["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz"; //最大線程數 props["quartz.threadPool.threadCount"] = "10"; //線程優先級:正常 props["quartz.threadPool.threadPriority"] = "Normal"; //初始化調度器 IScheduler scheduler = new StdSchedulerFactory(props).GetScheduler(); //Cron 觸發器,每隔 1 秒觸發一次 ITrigger trig = TriggerBuilder.Create().WithCronSchedule("0/1 * * * * ?").Build(); //將做業 Job1 加入調度計劃中 scheduler.ScheduleJob(JobBuilder.Create<Job1>().Build(), trig); //開始執行 scheduler.Start(); Console.ReadLine(); scheduler.Shutdown(); } }
執行結果以下:能夠看到,Job1 準確的每隔 1 秒執行一次框架
如今問題來了:若是 Job1 中的操做執行時間很長,超過了間隔時間 1 秒,會發生什麼狀況?代碼以下:ui
public class Job1 : IJob { public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now + ": Job1" + m); //等待 5 秒 Thread.Sleep(5000); } }
執行結果以下:spa
咱們會發現,Quartz 仍然會按照咱們設定的每隔 1 秒觸發一次。線程
這是由於默認狀況下,當Job執行時間超過間隔時間時,調度框架爲了能讓任務按照咱們預約的時間間隔執行,會立刻啓用新的線程執行任務。code
若咱們但願當前任務執行完以後再執行下一輪任務,也就是不要併發執行任務,該如何解決呢?orm
第一種方法:設置 quartz.threadPool.threadCount 最大線程數爲 1。這樣到了第二次執行任務時,若當前還沒執行完,調度器想新開一個線程執行任務,但咱們卻設置了最大線程數爲 1 個(即:沒有足夠的線程提供給調度器),則調度器會等待當前任務執行完以後,再當即調度執行下一次任務。(注意:此方法僅適用於Quartz中僅有一個Job,若是有多個Job,會影響其餘Job的執行)blog
第二種方法:在 Job 類的頭部加上 [DisallowConcurrentExecution],表示禁用併發執行。(推薦使用此方法)string
//不容許此 Job 併發執行任務(禁止新開線程執行) [DisallowConcurrentExecution] public class Job1 : IJob { }