26


6

System.Threading.Timerはどの程度スケーラブルですか?

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

言い換えれば、もう1つの方法があります。 `System.Threading.Timer`はどのように実装されていますか。

4 Answer


29


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

残念ながら、この特定のケースでは、実装の多くがネイティブコードで行われているので、それを見ることはできません…​

ただし、タイマーごとのスレッドではなくプールスレッドを確実に使用します。

大量のタイマーを実装する標準的な方法(これはカーネルが内部的に行う方法です。間接的には、大量のタイマーのコレクションが最終的にどのようになるかと思います)は、リストをtime-until-expiryでソートするのです。システムは、リスト全体ではなく、期限切れになる次のタイマーをチェックすることだけを心配する必要があります。

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

編集:ちょうどジェフリヒターの本を見てきました。 彼は、(Threading.Timerの)それがすべてのTimerオブジェクトのために単一のスレッドを使うと言っています、このスレッドはいつ次のタイマー(すなわち 上記のように)期限が切れており、必要に応じてコールバック用にThreadPool.QueueUserWorkItemを呼び出します。 これは、次の期限が切れる前にタイマーで1つのコールバックを処理し終えないと、そのコールバックが別のプールスレッドに再入力するという効果があります。 要約すると、たくさんのタイマーを使用することに大きな問題があるとは思わないでしょうが、多数のタイマーが同じタイマーで起動したりコールバックの実行が遅くなったりすると、スレッドプールが使い果たされる可能性があります。


7


私はあなたがあなたのデザインを再考したいと思うかもしれないと思います(つまり、あなたがデザインを自分でコントロールする場合)。 あまりにも多くのタイマーを使用していて、これが実際にはあなたにとっての関心事である場合、そこに統合の可能性があることは明らかです。

これは、数年前のMSDN Magazineの優れた記事で、3つの利用可能なタイマークラスを比較し、それらの実装に関する洞察を提供しています。


5


_ それらを統合します。 タイマーサービスを作成し、タイマーを依頼します。 それはただ1つのアクティブタイマーを維持する必要があるでしょう(次の期限付き呼び出しのために)…​ _

これが単にThreading.Timerオブジェクトを多数作成することを改善するためには、Threading.Timerがすでに内部的に行っていることとは異なることを前提とする必要があります。 あなたがその結論に至った経緯を知りたいと思います(私はフレームワークのネイティブ部分を逆アセンブルしていないので、あなたは正しいかもしれません)。


0


DannySmurfが言うように^^:それらを統合する。 タイマーサービスを作成し、タイマーを依頼します。 それは1つのアクティブタイマー(次の期限付き呼び出し用)とすべてのタイマー要求の履歴を保持し、AddTimer()/ RemoveTimer()でこれを再計算するだけで済みます。