2010-03-03 61 views
5

我正在處理請求超時機制。我最初的做法是爲每個請求創建一個System.Threading.Timer。併發請求的數量可以擴展到數千。System.Threading.Timer對於數千個併發定時器是否足夠高效?

我想知道是否應該創建一個TimeoutScheduler,它只能在內部使用一個計時器,而不是每個請求都有一個計時器。

任何知道System.Threading.Timer內部的人都會給我一些關於TimeoutScheduler是否是一個好主意或者它只會嘗試優化已經足夠高效的東西的見解。

注意:對於我的情況,計時器精度並不重要。

(我做了一些System.Threading.Timer性能測試與很多併發定時器。它似乎很好地擴展,但我不知道這是否會放不必要的壓力在真實系統)

回答

11

我將引導您到這個職位從雷蒙德陳:

What is the maximum number of timers a program can create?

技術上有與創建成千上萬的沒有問題。請注意,這些使用全局系統資源,所以如果你瘋了,你會最終達到一個上限和/或開始捱餓其他程序(包括Windows本身)。

另外確保在處理完它們之後處理定時器,否則最終會導致巨大的資源泄漏。


我不得不說,這聽起來像你可以用一個計時器實現的東西;只是維護一個活動請求和超時的字典,並在每個滴答聲上查看整個字典並檢查每個條目。您可以通過將其作爲排序列表來提高性能;這樣,如果沒有任何東西超時5分鐘,則在查看第一個條目後,tick方法將退出。

除上述內容外,您還可以動態調整滴答間隔以在下一個請求計劃超時時觸發;然後在每個時間點上,重新安排下一個超時時間。這實際上不會佔用系統資源(只有一個計時器),而且速度也非常快(正如您的每次一次請求的想法一樣,當請求實際到期時,您只會運行昂貴的代碼)。

即使你可以創建數以千計的定時器,上述方法將擴展得更好,也將更容易測試和維護。

+0

Raymond Chen的文章描述了一種不同類型的計時器。 – SLaks 2010-03-03 21:32:56

+0

@SLaks:Raymond Chen的文章沒有描述任何特定種類的計時器。他最後提到了Windows Forms計時器,並且我向你保證,我很清楚它們的區別,但**所有** .NET計時器都包含Windows計時器,並且都受到相同的警告。 – Aaronaught 2010-03-03 22:42:46

+1

實際上,Raymond Chen的文章描述了由SetTimer創建的定時器。 System.Threading.Timer實際上是一個定時器隊列定時器(http://msdn.microsoft.com/en-us/library/ms686796(v=VS.85).aspx),它基本上是一個單獨的定時器,一個確定何時觸發下一個事件的有效機制。 – 2010-09-02 23:58:04

1

超時調度程序是一個好主意,但定時器是最低優先級的執行。如果這是計劃超時,那麼最可靠的選項將成爲跟蹤其他線程的超時以及使用QueryPerormanceCounter和QueryPerformanceFrequency更新的線程。這些將阻止類,但在他們自己的線程內,這並不重要。您也可以考慮使超時調度程序以更高的優先級運行。

1

System.Threading.Timer在ThreadPool上執行它的TimerCallback,創建1000可能導致線程池不足。

MSDN System.Threating.Timer

使用TimerCallback委託指定要定時執行的方法。計時器委託在構造計時器時指定,並且不能更改。該方法不會在創建定時器的線程上執行;它在系統提供的ThreadPool線程上執行。

System.Timers.Timer的行爲方式相同。 TimeoutScheduler是要走的路。