2014-09-04 45 views
3

如果作業與其他作業同時被觸發,QuartzNet默認只使用作業的優先級。但是,如果在不同時間觸發兩個作業,則最早的作業將始終首先在線程池中運行。我有一個場景,但我需要隊列中最高優先級的作業,以便始終在下一個線程上運行。有沒有簡單的方法用Quartz.Net來做到這一點,或者如果我想完成這個工作,我將不得不實現自己的調度器? (或轉移到其他技術)。你可以讓Quartz.Net使用優先級隊列嗎?

我想到的具體情景: 定期工作將以高優先級觸發,可能會爲另一個進程產生一些輸出。儘量減少等待時間非常重要。但是,我也有時候可能會以低得多的優先級同時觸發多達數千個工作。我擔心,當這些「批次」被觸發時,更重要的工作將等待很長時間才能運行。

有沒有一種簡單的方法來做到這一點與Quartz.Net或競爭對手的技術?

+0

您能否使用TPL或BackgroundWorker在單獨的線程上切實執行長時間運行的操作?我設置了一個快速測試,觸發了會阻塞很長一段時間的工作,Quartz在延遲進一步的工作之前給了我4個線程,但是當在Task.Factory.StartNew中封裝Execute方法的阻塞部分時,我的觸發器繼續觸發而這些線程繼續在後臺運行。 – raney 2014-09-04 04:27:26

回答

0

你見過觸發優先權嗎?我不認爲它會在不同的線程上運行它,但它會推動作業在以前優先級較低的另一個作業之前啓動。

Trigger trigger = TriggerBuilder.Create() 
    .WithIdentity("TestTrigger") 
    .StartNow() 
    .WithPriority(10) 
    .Build(); 
+0

我的問題是,只考慮同時觸發的作業的優先級。 IE,如果具有優先級1的作業在12:00被觸發,並且具有優先級爲10 @ 12:01的作業,則該作業將始終首先運行。我不介意這種情況,如果一個線程可用,那麼它就會啓動,我擔心當我觸發更多的工作而不是一次提供的線程時,我會遇到一個場景,高優先級的作業不會運行時期(也許幾分鐘)。 – Sethcran 2014-09-04 02:47:31

+0

您的工作是否都在一個調度程序類中? – Papa 2014-09-04 03:40:45

+0

是的。我提到的「批處理」工作基本上是在許多不同的環境(數據庫)中運行的相同工作。目前,我有一個JobA ,其中T:IJob確定作業需要動態運行的所有位置,然後使用不同參數爲每個作業調度一個作業詳細信息,這些參數全部在同一個調度程序上。 – Sethcran 2014-09-04 03:45:31

0

正如你所說,這不是Quartz.Net直接支持。您可以創建自己的調度程序(請參見下文),或者如果您通過更新QRTZ_TRIGGERS表中的NEXT_FIRE_TIME列來使用數據庫存儲,則可以解決該問題。如果您更新NEXT_FIRE_TIMEs,以便按照優先級排序它們,則下次調度程序檢查計劃更改時,您的作業將按優先順序執行。

上有QuartzScheduler,你可以更新消防倍,但不幸的是它不是由StdScheduler暴露後調用

public void SignalSchedulingChange(DateTimeOffset? candidateNewNextFireTimeUtc) 

方法。如果你要走「我自己的調度程序」路線,你可以直接調用它。否則,在調度程序上調用ScheduleJob方法(以及調度作業)也會調用此方法,以便在更新下一次着火時間後利用該方法並安排作業。

0

實施這種行爲的最簡單的方法是繼承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"); 
    } 
} 

請記住,這可能導致長時間的延遲低優先級的工作,如果調度程序被高優先級的調度程序淹沒了。

我還沒有自己嘗試過,但可能值得考慮某種混合方法,它以某種方式平衡了PRIORITYNEXT_FIRE_TIME值。例如,您可以從下一次着火時間中減去優先級,以創建一種可變大小的優先級窗口。

order by dateadd(ss, -PRIORITY, NEXT_FIRE_TIME) 

因此,如果一個優先級= 10的觸發器觸發時間不超過5秒,那麼它只會觸發優先級= 5的觸發器。只是一個想法。