実行時の統計情報の収集を実装しようとしていると思います。たとえば、送信したバイト数、実行時間、ユーザーが特定の機能をアクティブにした回数などです。
通常、さまざまなソース(ワーカースレッドなど)からのこれらのようなランタイム統計をコンパイルするために、各ソース(スレッド)に最も基本的なデータの独自のローカルカウンターをインクリメントさせますが、長い計算やそのデータの分析はまだです。
次に、メインスレッド(またはこれらの統計を分析して表示する場所)に戻り、RequestProgress
各ワーカースレッドにタイプメッセージを送信します。それに応じて、ワーカースレッドはすべての基本データを収集し、おそらくいくつかの簡単な分析を実行します。このデータは、基本的な分析の結果とともに、メッセージで要求元の(メイン)スレッドに返送されProgressReport
ます。次に、メインスレッドはこのすべてのデータを集約し、追加の(おそらくコストのかかる)分析、フォーマット、およびユーザーへの表示またはログ記録を行います。
メインスレッドRequestProgress
は、ユーザーの要求(S
キーを押したときなど)または時間間隔でこのメッセージを送信します。時間間隔が目的の場合は、通常、別の新しい「ハートビート」スレッドを実装します。このスレッドが行うのはSleep()
、指定された時間だけです。その後Heartbeat
、メインスレッドにメッセージを送信します。次に、メインスレッドは、統計が収集されるすべてのワーカースレッドにメッセージをHeartbeat
送信することにより、このメッセージに作用します。RequestProgress
統計を収集するという行為は、かなり簡単なはずです。では、なぜこのような複雑なメカニズムなのですか?答えは2つあります。
まず、ワーカースレッドにはやるべき仕事があり、使用統計の計算はそうではありません。これらのスレッドをリファクタリングして、主な目的に正統な2番目の責任を引き受けようとするのは、四角いペグを丸い穴に押し込もうとするのと少し似ています。それらはそれを行うように構築されていないので、コードは書かれることに抵抗します。
第2に、実行時の統計の計算は、あまりにも頻繁に実行しようとするとコストがかかる可能性があります。たとえば、ネットワーク上でマルチキャストデータを送信するワーカースレッドがあり、スループットデータを収集するとします。何バイト、どのくらいの期間、そして1秒あたりの平均バイト数。ワーカースレッドにこれらすべてをオンザフライで計算させることもできますが、それは多くの作業であり、そのCPU時間は、ワーカースレッドが本来の処理(マルチキャストデータの送信)を実行する方が適切です。代わりに、メッセージを送信するたびに送信したバイト数のカウンターを単純にインクリメントした場合、カウントによるスレッドのパフォーマンスへの影響は最小限に抑えられます。その後、時折に応じてRequestProgress
メッセージを送信して、開始時刻と停止時刻を把握し、それを送信して、メインスレッドにすべての分割などを実行させることができます。