一個普通的 Job 實現(xiàn)如下:
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"; //最大線程數(shù) props["quartz.threadPool.threadCount"] = "10"; //線程優(yōu)先級:正常 props["quartz.threadPool.threadPriority"] = "Normal"; //初始化調(diào)度器 IScheduler scheduler = new StdSchedulerFactory(props).GetScheduler(); //Cron 觸發(fā)器,每隔 1 秒觸發(fā)一次 ITrigger trig = TriggerBuilder.Create().WithCronSchedule("0/1 * * * * ?").Build(); //將作業(yè) Job1 加入調(diào)度計劃中 scheduler.ScheduleJob(JobBuilder.Create<Job1>().Build(), trig); //開始執(zhí)行 scheduler.Start(); Console.ReadLine(); scheduler.Shutdown(); }}執(zhí)行結(jié)果如下:可以看到,Job1 準確的每隔 1 秒執(zhí)行一次

現(xiàn)在問題來了:如果 Job1 中的操作執(zhí)行時間很長,超過了間隔時間 1 秒,會發(fā)生什么情況?代碼如下:
public class Job1 : IJob{ public void Execute(IJobExecutionContext context) { Console.WriteLine(DateTime.Now + ": Job1" + m); //等待 5 秒 Thread.Sleep(5000); }}執(zhí)行結(jié)果如下:

我們會發(fā)現(xiàn),Quartz 仍然會按照我們設(shè)定的每隔 1 秒觸發(fā)一次。
這是因為默認情況下,當(dāng)Job執(zhí)行時間超過間隔時間時,調(diào)度框架為了能讓任務(wù)按照我們預(yù)定的時間間隔執(zhí)行,會馬上啟用新的線程執(zhí)行任務(wù)。
若我們希望當(dāng)前任務(wù)執(zhí)行完之后再執(zhí)行下一輪任務(wù),也就是不要并發(fā)執(zhí)行任務(wù),該如何解決呢?
第一種方法:設(shè)置quartz.threadPool.threadCount 最大線程數(shù)為 1。這樣到了第二次執(zhí)行任務(wù)時,若當(dāng)前還沒執(zhí)行完,調(diào)度器想新開一個線程執(zhí)行任務(wù),但我們卻設(shè)置了最大線程數(shù)為 1 個(即:沒有足夠的線程提供給調(diào)度器),則調(diào)度器會等待當(dāng)前任務(wù)執(zhí)行完之后,再立即調(diào)度執(zhí)行下一次任務(wù)。(注意:此方法僅適用于Quartz中僅有一個Job,如果有多個Job,會影響其他Job的執(zhí)行)
第二種方法:在 Job 類的頭部加上[DisallowConcurrentExecution],表示禁用并發(fā)執(zhí)行。(推薦使用此方法)
//不允許此 Job 并發(fā)執(zhí)行任務(wù)(禁止新開線程執(zhí)行)[DisallowConcurrentExecution]public class Job1 : IJob{}新聞熱點
疑難解答