實施這種行爲的最簡單的方法是繼承StdAdoDelegate
(或DB具體的實現方式之一),並覆蓋GetSelectNextTriggerToAcquireSql
,使其NEXT_FIRE_TIME
,而不是之前排序由PRIORITY
。
下面的類獲取默認的SQL查詢和使用的條款的臨時空字符佔位符的幫助下交換順序:
public class CustomAdoDelegate : StdAdoDelegate
{
protected override string GetSelectNextTriggerToAcquireSql(int maxCount)
{
return base.GetSelectNextTriggerToAcquireSql(maxCount)
.Replace(ColumnNextFireTime + " ASC", "\0")
.Replace(ColumnPriority + " DESC", ColumnNextFireTime + " ASC")
.Replace("\0", ColumnPriority + " DESC");
}
}
請記住,這可能導致長時間的延遲低優先級的工作,如果調度程序被高優先級的調度程序淹沒了。
我還沒有自己嘗試過,但可能值得考慮某種混合方法,它以某種方式平衡了PRIORITY
和NEXT_FIRE_TIME
值。例如,您可以從下一次着火時間中減去優先級,以創建一種可變大小的優先級窗口。
order by dateadd(ss, -PRIORITY, NEXT_FIRE_TIME)
因此,如果一個優先級= 10的觸發器觸發時間不超過5秒,那麼它只會觸發優先級= 5的觸發器。只是一個想法。
您能否使用TPL或BackgroundWorker在單獨的線程上切實執行長時間運行的操作?我設置了一個快速測試,觸發了會阻塞很長一段時間的工作,Quartz在延遲進一步的工作之前給了我4個線程,但是當在Task.Factory.StartNew中封裝Execute方法的阻塞部分時,我的觸發器繼續觸發而這些線程繼續在後臺運行。 – raney 2014-09-04 04:27:26