2

背景:私はすでにスレッドシステムが設計されているアプリケーションに取り組んでいます。最適とは程遠いですが、現時点ではやり直せません。.netの新しいスレッド構造は使用せず、基本Threadオブジェクトとスレッド処理ロジックをラップするオブジェクトのみを使用します。

一般的な設定は次のとおりです。(現在、2つのグループ、またはスレッドのカテゴリがあります)

  • ワーカースレッドを生成するメインアプリケーションスレッド(statthread main)。

  • ワーカースレッド。それぞれにThreadオブジェクトがあり、すべての処理を行う/スレッド間の境界などを処理するワーカーオブジェクトがあります。各スレッドはジョブを実行し、各ジョブには。がありJobTypeIDます。

ワーカーを制御するための3番目のタイプのスレッドを導入する必要があります。これらの制御メッセージは、awcf Webサービスから送信されます(したがって、このスレッドは暗黙的に処理されます)。

制御メッセージは次のとおりです。{一時停止/再開、IDのリスト}

私の目標:

スレッドがジョブを処理している場合に、このスレッドのすべてのジョブを一時停止するようにというメッセージが表示されるように、これらのスレッドを同期するための最良の方法を見つけようとしていますJobTypeID。履歴書が送信されるまでブロックする必要があります(そのIDの場合) )。ここでの落とし穴は、メッセージが送信された時点で、関連するジョブが処理されていない可能性があるため、すぐにアクションを実行する必要がないことです。また、ワーカーオブジェクトのリストがないため、単純に処理することはできません。各ワーカーを繰り返し処理し、if-matches-then-pauseを実行します。

実際の質問(一般化) 一連のワーカースレッド、スポナー/マネージャースレッド、および一連の制御スレッドを同期するために、皆さんは何をお勧めしますか?

私が試したこと

1つのアプローチは、ManualResetEventオブジェクトのコレクションを1つずつ格納JobTypeIDし、着信メッセージに従ってそれらに信号を送り、待機することです。このアプローチについてどう思いますか?プロセスに100以上の待機ハンドルがある場合のベストプラクティスまたはメモリ/処理コストに関する情報が見つかりません。

別のアプローチは、すべてのスレッドが待機する単一のオブジェクトを持ち、その同期されたコレクションがJobTypeIDs待機することです。私はこのアプローチでいくつかの問題を抱えています。ManualResetEventつまり、1つのジョブIDを再開しても、他のジョブIDが待機している場合は、set(); reset();を実行する必要があります。これにより、いくつかの競合状態が発生します(WaitHandle.SignalAndWait(x、x)を実行しようとしても))最後に、Monitor.PulseAll()を使用して機能するソリューションを考え出しました。

たくさんのロックオブジェクトを備えたモニターを使用することもできます。これは、たくさんのウェイトハンドルよりも軽量であるように思われます。

また、長い質問とお読みいただきありがとうございます!

4

1 に答える 1

2

を作成しますConcurrentDictionary<JobTypeId, ManualResetEvent>。通常、辞書には。のエントリはありませんJobTypeId。そのようなエントリが存在するのは、そのジョブタイプがブロックされることになっているときだけです。

そのジョブタイプがブロックされることになっている場合は、シグナルのないを作成し、ManualResetEventそれをディクショナリに追加します。キーはJobTypeIdブロックされます。

したがって、ワーカースレッドには次のようなループがあります。

while (still_have_work_to_do)
{
    ManualResetEvent mevent;
    if (PauseDictionary.TryGetValue(myJobTypeId, out mevent))
    {
        // wait until the event is signaled.
        mevent.WaitOne();
    }

    // Do more processing.
}

スポナースレッドは、ディクショナリにクエリを実行して、特定のタイプのワーカーをスポーンできるかどうかを確認することもできます。ワーカーを作成できない場合は、そのジョブを破棄するか、後でチェックするために再キューに入れます。投票する頻度はあなた次第です。

WaitHandle1つのプロセスに数百のオブジェクトがあることに特に問題はありません。オブジェクトの束はより少ないシステムリソースを必要とするかもしれませんが、 (または)は実際には相互排除デバイスであるMonitorことを忘れないでください。いくつかの点でそれをのように振る舞わせるために愚かなことをすることができますが、テクニックは自明ではないので、理解しにくく、壊れやすいコードになります。MonitorlockWaitHandle

于 2011-12-29T17:47:56.713 に答える