2008-08-28 40 views
26

我正在編寫一個應用程序,需要使用Timer s,但可能很多。 System.Threading.Timer類的可擴展性如何?該文件只是說它是「輕量級」的,但沒有進一步解釋。這些定時器是否會被吸入單個線程(或非常小的線程池)中,以代表Timer處理所有回調,還是每個Timer都有自己的線程?System.Threading.Timer如何擴展?

我想用另一種方法來重述這個問題是:System.Threading.Timer如何實現?

回答

29

我說,這響應了很多問題:不要忘記框架的(託管)源代碼可用。您可以使用此工具來得到這一切:http://www.codeplex.com/NetMassDownloader

不幸的是,在這種特定的情況下,大量的執行是在本機代碼,所以你不要看它......

他們不過,必須使用線程池而不是每個線程。

實現大量計時器的標準方法(這是內核如何在內部完成的,我懷疑是間接如何定時器的大集合的結果)是維護按時間排序的列表,到期 - 所以系統只需要擔心檢查即將到期的下一個計時器,而不是整個列表。大致上,這給出了用於啓動定時器的O(log n)和用於處理運行定時器的O(1)。

編輯:剛剛在傑夫裏希特的書看。他說(Threading.Timer)它對所有Timer對象使用單個線程,該線程知道下一個計時器(即如上)何時到期,並根據需要調用ThreadPool.QueueUserWorkItem來獲取回調。這樣做的結果是,如果在下一個到期之前沒有完成一個定時器的回調服務,那麼您的回調將重新進入另一個池線程。總之,我懷疑你會遇到大量計時器的大問題,但如果大量計時器觸發同一個計時器和/或其回調運行緩慢,則可能導致線程池耗盡。

+0

優先級隊列可能比排序列表更有效,除非所有定時器在開始時被批量添加,然後排序,並且以後不再添加更多定時器。 – RAL 2010-02-25 04:39:15

7

我想你可能想重新考慮你的設計(也就是說,如果你自己可以控制設計)。如果你使用這麼多定時器,這實際上是你的關注點,那麼顯然有一些潛在的整合潛力。

下面是從MSDN雜誌從幾年前的一篇好文章,這三個可用的定時器類進行比較,並給出了一些洞察他們的實現:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

0

^^ DannySmurf說:鞏固他們。創建一個計時器服務,並要求定時器。它只需要保留1個活動定時器(用於下一個應有的調用)和所有定時器請求的歷史記錄,並在AddTimer()/ RemoveTimer()上重新計算。

5

合併它們。創建一個定時器 服務並請求定時器。 它將只需要保持1個活躍 定時器(今後由於調用)...

爲這是一種改進過剛剛創建大量Threading.Timer的對象,你必須假設它不是這正是Threading.Timer已經在內部完成的事情。我有興趣知道你是如何得出這個結論的(我沒有反編譯框架的本地部分,所以你可能是對的)。