我正在編寫一個應用程序,需要使用Timer
s,但可能很多。 System.Threading.Timer
類的可擴展性如何?該文件只是說它是「輕量級」的,但沒有進一步解釋。這些定時器是否會被吸入單個線程(或非常小的線程池)中,以代表Timer
處理所有回調,還是每個Timer
都有自己的線程?System.Threading.Timer如何擴展?
我想用另一種方法來重述這個問題是:System.Threading.Timer
如何實現?
我正在編寫一個應用程序,需要使用Timer
s,但可能很多。 System.Threading.Timer
類的可擴展性如何?該文件只是說它是「輕量級」的,但沒有進一步解釋。這些定時器是否會被吸入單個線程(或非常小的線程池)中,以代表Timer
處理所有回調,還是每個Timer
都有自己的線程?System.Threading.Timer如何擴展?
我想用另一種方法來重述這個問題是:System.Threading.Timer
如何實現?
我說,這響應了很多問題:不要忘記框架的(託管)源代碼可用。您可以使用此工具來得到這一切:http://www.codeplex.com/NetMassDownloader
不幸的是,在這種特定的情況下,大量的執行是在本機代碼,所以你不要看它......
他們不過,必須使用線程池而不是每個線程。
實現大量計時器的標準方法(這是內核如何在內部完成的,我懷疑是間接如何定時器的大集合的結果)是維護按時間排序的列表,到期 - 所以系統只需要擔心檢查即將到期的下一個計時器,而不是整個列表。大致上,這給出了用於啓動定時器的O(log n)和用於處理運行定時器的O(1)。
編輯:剛剛在傑夫裏希特的書看。他說(Threading.Timer)它對所有Timer對象使用單個線程,該線程知道下一個計時器(即如上)何時到期,並根據需要調用ThreadPool.QueueUserWorkItem來獲取回調。這樣做的結果是,如果在下一個到期之前沒有完成一個定時器的回調服務,那麼您的回調將重新進入另一個池線程。總之,我懷疑你會遇到大量計時器的大問題,但如果大量計時器觸發同一個計時器和/或其回調運行緩慢,則可能導致線程池耗盡。
我想你可能想重新考慮你的設計(也就是說,如果你自己可以控制設計)。如果你使用這麼多定時器,這實際上是你的關注點,那麼顯然有一些潛在的整合潛力。
下面是從MSDN雜誌從幾年前的一篇好文章,這三個可用的定時器類進行比較,並給出了一些洞察他們的實現:
^^ DannySmurf說:鞏固他們。創建一個計時器服務,並要求定時器。它只需要保留1個活動定時器(用於下一個應有的調用)和所有定時器請求的歷史記錄,並在AddTimer()/ RemoveTimer()上重新計算。
合併它們。創建一個定時器 服務並請求定時器。 它將只需要保持1個活躍 定時器(今後由於調用)...
爲這是一種改進過剛剛創建大量Threading.Timer的對象,你必須假設它不是這正是Threading.Timer已經在內部完成的事情。我有興趣知道你是如何得出這個結論的(我沒有反編譯框架的本地部分,所以你可能是對的)。
優先級隊列可能比排序列表更有效,除非所有定時器在開始時被批量添加,然後排序,並且以後不再添加更多定時器。 – RAL 2010-02-25 04:39:15