26

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

質問を言い換える別の方法は次のとおりだと思います:どのようにSystem.Threading.Timer実装されていますか?

4

4 に答える 4

29

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

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

ただし、タイマーごとのスレッドではなく、プールスレッドを使用することは間違いありません。

タイマーの大きなコレクションを実装する標準的な方法 (これはカーネルが内部で行う方法であり、タイマーの大きなコレクションが間接的にどのように終了するかであると思われます) は、有効期限までの時間で並べ替えられたリストを維持することです。システムは、リスト全体ではなく、期限切れになる次のタイマーをチェックすることだけを心配する必要があります。

大まかに言えば、これにより、タイマーを開始するための O(log n) と、実行中のタイマーを処理するための O(1) が得られます。

編集: Jeff Richter の本を見ているところです。彼は、(Threading.Timer について) すべての Timer オブジェクトに対して単一のスレッドを使用すると述べています。このスレッドは、次のタイマー (つまり、上記のように) の期限を認識しており、必要に応じてコールバックのために ThreadPool.QueueUserWorkItem を呼び出します。これには、次の期限が来る前にタイマーで 1 つのコールバックのサービスを終了しない場合、そのコールバックが別のプール スレッドで再入力されるという効果があります。要約すると、多くのタイマーを使用することで大きな問題が発生することはないと思いますが、多数のタイマーが同じタイマーで起動したり、コールバックの実行が遅い場合は、スレッド プールが枯渇する可能性があります。

于 2008-08-28T08:12:24.270 に答える
7

設計を再考することをお勧めします (つまり、設計を自分で制御できる場合)。非常に多くのタイマーを使用していて、これが実際に問題になっている場合は、統合の可能性があることは明らかです。

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

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

于 2008-08-28T07:23:25.433 に答える
5

それらを統合します。タイマー サービスを作成し、タイマーを要求します。アクティブなタイマーを 1 つ保持するだけで済みます (次の通話のために)...

多くの Threading.Timer オブジェクトを作成するだけでこれが改善されるためには、Threading.Timer が内部で既に行っていることとまったく同じではないことを想定する必要があります。どのようにしてその結論に達したのか知りたいです (私はフレームワークのネイティブ部分を分解していないので、あなたは正しいかもしれません)。

于 2008-08-28T09:34:14.137 に答える
0

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

于 2008-08-28T08:46:29.463 に答える