2011-12-29 14 views
2

背景: 私は既にスレッドシステムを設計しているアプリケーションで作業しています。最適ではありませんが、現時点では修正できません。これは、.netの新しいスレッディングコンストラクト、基本的なThreadオブジェクト、およびスレッド処理ロジックをラップするオブジェクトを使用しません。複数のスレッドを.netで同期する

それの一般的なセットアップは、次のとおりです。ワーカースレッドを生成します

  • メインアプリケーションスレッド(メインstatthread)(二つのグループ、または今のスレッドのカテゴリがあります)。

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

第3の種類のスレッドを導入する必要があります。これは、作業者を制御するためのものです。これらの制御メッセージは、wcf Webサービスから来ます(したがって、このスレッドは暗黙的に処理されます)。

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

私の目標:

私はそのようにこれらのスレッドを同期させるために何を最善の方法を把握しようとしていますスレッドがジョブを処理しており、このJobTypeIDのすべてのジョブを一時停止するというメッセージが表示された場合は、そのIDの再開が送信されるまでブロックされます。ここでのキャッチは、メッセージが送信された時点では、関連するジョブが処理されない可能性があるため、即座のアクションを実行する必要はなく、ワーカーオブジェクトのリストもないため、単純に各作業者を繰り返し処理し、if-matches-then-pauseを実行します。

実際の質問(一般) 君たちは私がワーカースレッドのセット、産卵/マネージャスレッド、および制御スレッドのセットを同期させるために何を勧めますか?

物事私が試した

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

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

ロックオブジェクトがたくさんあるモニターを使用することもできます。これは、たくさんのウォーターサンダーよりも軽量であるようです。

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

+0

いくつかの質問: 1.すべてのワーカースレッドが単一JobTypeIdの責任ですか?または、すべてのスレッドは利用可能なものを処理しますか?一時停止メッセージが受信されると、あるスレッドの処理ジョブを完全に一時停止するか、一時停止したジョブをスキップして他の処理を続行する必要がありますか? 2.ワーカースレッドはいくつありますか? 3.一時停止メッセージが受信されたときにワーカースレッドがジョブを処理する場合、ジョブを終了させたり、途中で何とか一時停止させたりしますか? – ttil

答えて

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. 
} 

を産卵スレッドはまた、労働者の特定のタイプを生成できるかどうかを確認するために辞書を照会することができます。ワーカーを作成できない場合は、そのジョブを廃棄するか、後でチェックするようにジョブを再キューします。投票する頻度はあなた次第です。

単一プロセスでWaitHandle数百個のオブジェクトを持つ特段の問題はありません。 Monitorのオブジェクトは、システムリソースを減らす可能性がありますが、Monitor(またはlock)は実際には相互排除デバイスです。いくつかの点でWaitHandleのように振る舞うように愚かなことをすることはできますが、技術は分かりにくく、理解しにくく、脆弱なコードにつながります。

関連する問題