2008-08-28 6 views
26

私はTimerを利用する必要があるが、潜在的に非常に多くのアプリを書いている。どのようにスケーラブルなSystem.Threading.Timerクラスですか?ドキュメントでは「軽量」としか言いませんが、それ以上は説明しません。これらのタイマーは、Timerの代わりにすべてのコールバックを処理する単一のスレッド(または非常に小さなスレッドプール)に吸い込まれるのですか、またはそれぞれTimerに独自のスレッドがありますか?System.Threading.Timerのスケーラビリティは?

質問を言い換えると、もう1つの方法は:System.Threading.Timerはどのように実装されていますか?

答えて

29

質問:フレームワークへの(管理された)ソースコードが利用可能であることを忘れないでください。あなたはそれをすべて取得するには、このツールを使用することができます。http://www.codeplex.com/NetMassDownloader

残念ながら、この特定のケースでは、実装の多くは、ネイティブコードであるので、あなたはそれを見るために得ることはありません...

彼らは、しかし、スレッドごとのスレッドではなくプールスレッドを使用することは間違いありません。

大きなコレクションのタイマーを実装する標準的な方法(カーネルが内部的にどのようにしているのか、間接的にタイマーの大きなコレクションがどのように終わっているのか疑うでしょう)は、リストをtime-満了 - システムは、リスト全体ではなく、期限切れになる予定の次のタイマーのチェックについて心配する必要があります。

これは、おおよそ、タイマーを開始するためのO(log n)と、実行中のタイマーを処理するためのO(1)を与えます。

編集:ちょうどJeff Richterの本を見ていた。彼は(Threading.Timerの)スレッドがすべてのTimerオブジェクトに対して単一のスレッドを使用していると言いますが、このスレッドは次のタイマー(つまり上のとおり)が期限切れであることを知り、必要に応じてコールバックをThreadPool.QueueUserWorkItemを呼び出します。これは、次の期限前にタイマーで1つのコールバックを処理し終わらないと、コールバックが別のプールスレッドに再入されるという効果があります。要約すると、たくさんのタイマーを持つことで大きな問題が発生するのではないかと疑いますが、同じタイマーで多数のスレッドが起動したり、コールバックが遅い場合にスレッドプールが枯渇する可能性があります。

+0

優先度キューは、すべてのタイマーが最初に一括して追加され、並べ替えられ、後で追加されない限り、並べ替え済みリストより効率的です。 – RAL

+0

確かに - 「期限切れのリストは確かに一種の優先待ち行列かもしれません - 私はソート操作を実行したリストを暗示するつもりはありません」 –

+1

私はちょうど時間を過ごしましたsscliのコードを介して。 Rotorがリリースされて以来、.NET ThreadPoolが大幅に変更されたため、System.Threading.Timerも大幅に変更されている可能性があります。事実、タイマーは.NET 1.1ではひどく壊れていて、.NET 2.0では安全で安全な例外になるように固定されていました。 とにかく、Rotorではタイマはリンクされたリストに保持され、専用のTimer firingスレッドによって起動されます。ランタイム全体(複数のアプリケーションドメインにまたがっていても)に対して1つのタイマー起動スレッドがあります。 –

7

自分のデザインを考え直したいと思うかもしれません(自分でデザインをコントロールしている場合)。これが実際に懸念しているタイマーを非常に多く使用している場合は、そこに統合の可能性があります。

ここで利用可能な3つのタイマクラスを比較し、その実装にいくつかの洞察力を与える、数年前からMSDNマガジンから良い記事があります:多くのに応じて、私はこれを言う

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

0

^^ DannySmurfは言っています:それらを統合してください。タイマーサービスを作成し、タイマーを要求します。 1つのアクティブタイマー(次回のコールのため)とすべてのタイマーリクエストの履歴を保持し、AddTimer()/ RemoveTimer()でこれを再計算するだけで済みます。

5

これらを統合します。タイマー サービスを作成し、タイマーを要求してください。 それは、これは単なるThreading.Timerオブジェクトの多くを作成するよりも改善するために、あなたはそれがにISNと仮定しなければならない

...(次による呼び出し用)1つのアクティブ タイマーを維持するためにのみ必要となりますThreading.Timerが既に内部でやっていることはまったくありません。私はあなたがその結論にどのようになったのかを知ることに興味があります(私はフレームワークのネイティブビットを分解していないので、正しいかもしれません)。

関連する問題