Quartz.Net進階之二:關於觸發器的更多資訊
與作業一樣,觸發器相對容易使用,但是在您可以充分利用Quartz.NET/">Quartz.NET之前,確實需要了解和理解各種可自定義的選項。 此外,如前所述,您可以選擇不同型別的觸發器來滿足不同的排程需求。
1、常見觸發器屬性(Common Trigger Attributes)
除了所有觸發器型別都具有用於跟蹤其身份的TriggerKey屬性之外,還有許多其他屬性對所有觸發器型別都是通用的。 在構建觸發器定義時,使用TriggerBuilder設定這些常用屬性(後面將舉例說明)。
以下是所有觸發器型別共有的屬性列表:
1)、JobKey 屬性指示觸發器觸發時應該執行作業的標識。
2)、StartTimeUtc 屬性指示觸發器的計劃首次生效是什麼時候。該值是DateTimeOffset物件,用於定義給定日曆日期的時刻。對於某些觸發器型別,觸發器實際上會在開始時觸發,對於其他觸發器型別,它只是標記應該開始遵循排程的時間。這意味著您可以儲存一個觸發器,其中包含一個計劃,例如1月份的“每月的第5天”,如果StartTimeUtc屬性設定為4月1日,則會在第一次觸發前幾個月。
3)、EndTimeUtc 屬性指示觸發器的排程計劃何時不再有效。換句話說,具有“每月的第5天”和7月1日結束時間表的觸發器將在6月5日的最後一次觸發後將結束。
其他的屬性需要更多時間來解釋,將在以下小節中討論。
2、優先順序
有時,當您有許多觸發器(或Quartz.NET執行緒池中的工作執行緒比較少)時,Quartz.NET可能沒有足夠的資源來立即觸發計劃中該同時觸發的所有觸發器。 在這種情況下,您可能希望控制哪些觸發器在可用的Quartz.NET工作執行緒中首先觸發。為此,您可以在Trigger上設定priority屬性。 如果同時觸發N個觸發器,但是當前只有Z個工作執行緒可用,則首先執行具有最高優先順序的第一個Z觸發器。如果未在觸發器上設定優先順序,則它將使用預設優先順序5,優先順序的值可以是任何整數值,包括正數或者負數。
注意:優先順序僅在觸發器具有相同的啟用時間時才進行比較。定於10:59啟用的觸發器總是在定於11:00啟用的觸發器之前開火。
注意:當檢測到觸發器的作業需要恢復時,其恢復的排程優先順序與原始觸發器相同。
3、Misfire Instructions
觸發器的另一個重要特性是它的“失火指令”。 如果永續性觸發器由於排程程式被關閉而“錯過”其觸發時間,或者因為Quartz.NET的執行緒池中沒有可用於執行作業的執行緒,則會發生失敗。 不同的觸發型別可以使用不同的失火指令。 預設情況下,它們使用“智慧策略”指令 - 該指令具有基於觸發型別和配置的動態行為。 當排程程式啟動時,它會搜尋任何已失效的持久觸發器,然後根據各自配置的失火指令更新每個觸發器。 當您在自己的專案中開始使用Quartz.NET時,您應該熟悉在給定觸發器型別上定義的失火指令,並在其API文件中進行了解釋。 有關失火指令的更多具體資訊將在特定於每種觸發型別的教程課程中給出。
4、Calendars
實現ICalendar介面的Quartz.NET Calendar物件可以在觸發器儲存在排程程式中時與觸發器相關聯。 日曆可用於從觸發器的觸發計劃中排除時間塊。 例如,您可以建立一個觸發器,在每個工作日上午9:30觸發作業,但隨後新增一個排除所有業務假期的日曆。
Calendar可以是任何實現ICalendar介面的可序列化物件,如下所示:
1namespace Quartz 2{ 3public interface ICalendar 4{ 5string Description { get; set; } 6 7ICalendar CalendarBase { set; get; } 8 9bool IsTimeIncluded(DateTimeOffset timeUtc); 10 11DateTime GetNextIncludedTimeUtc(DateTimeOffset timeUtc); 12 13ICalendar Clone(); 14} 15}
儘管日曆物件可以“阻擋”只有一毫秒那麼短的時間段,但很可能,你會對“封鎖”整天的時間感興趣。 為方便起見,Quartz.NET包含了類HolidayCalendar,它就是這樣做的。
必須例項化日曆物件,並通過AddCalendar(..)方法向排程程式註冊日曆物件。如果使用HolidayCalendar,則在例項化它之後,應該使用它的AddExcludedDate(DateTime日期)方法,可以將從排程中排除的天數做引數傳遞給該方法。同一個日曆例項可以與多個觸發器一起使用,例如:
1HolidayCalendar cal = new HolidayCalendar(); 2cal.AddExcludedDate(someDate); 3 4await sched.AddCalendar("myHolidays", cal, false); 5 6ITrigger t = TriggerBuilder.Create() 7.WithIdentity("myTrigger") 8.ForJob("myJob") 9.WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(9, 30)) // execute job daily at 9:30 10.ModifiedByCalendar("myHolidays") // but not on holidays 11.Build(); 12 13// .. schedule job with trigger 14 15ITrigger t2 = TriggerBuilder.Create() 16.WithIdentity("myTrigger2") 17.ForJob("myJob2") 18.WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(11, 30)) // execute job daily at 11:30 19.ModifiedByCalendar("myHolidays") // but not on holidays 20.Build(); 21 22// .. schedule job with trigger2
觸發器的構造/構建的細節將在接下來的幾篇文章中給出。 現在,只要相信上面的程式碼建立了兩個觸發器,每個觸發器計劃每天觸發。 但是,將跳過在日曆排除的期間內發生的任何發射。
有關可能滿足您需求的許多ICalendar實現,請參閱Quartz.Impl.Calendar名稱空間。