ManualResetEvent経由でクロスプロセスイベントを作成しました。このイベントが発生すると、n個の異なるプロセスのn個のスレッドがブロックされ、新しいデータをフェッチするための実行が開始されます。問題は、ManualResetEvent.Setの直後に即時のリセットがあると、待機中のすべてのスレッドが起動することはないようです。ドキュメントはクロスプロセスイベント - すべてのウェイターを確実に解放します。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspxマニュアルリセットイベントオブジェクトの状態が通知され
は、それが明示的にResetEvent 機能によって非シグナルにリセットされるまで が合図のままそこにかなり漠然としています。オブジェクトの状態が通知されている間に、 が指定されたイベントオブジェクトの待機操作を開始する任意の数の待機スレッドまたはスレッドを解放できます。
PulseEventと呼ばれる方法がありますが、私が必要としているのとまったく同じように見えますが、残念ながらそれにも欠陥があります。
同期オブジェクト上で待機しているスレッドが一瞬 カーネルモードAPCで待機状態から除去され、APCが完了した後、その後、待機状態を に戻すことができます。スレッド 状態からスレッドが削除されている間にPulseEvent の呼び出しが発生した場合、PulseEventは が呼び出された時点で待機しているスレッドのみを解放するため、スレッドは解放されません。 したがって、PulseEventは信頼性が低く、新しい アプリケーションでは使用しないでください。代わりに、条件変数を使用します。
ここで、条件変数を使用することをおすすめします。
条件変数は、スレッド が特定の条件が発生するまで待つことを可能にする同期プリミティブです。条件変数は ユーザーモードオブジェクトです。はプロセス間で共有できません。
ドキュメントに続いて、私はそれを確実に実行する運が不足しているようです。 1つのManualResetEventで明記されている制限なしに同じことを達成する簡単な方法はありますか、各リスナープロセスに対してレスポンスイベントを作成して、各サブスクライブされた呼び出し元に対してACKを取得する必要がありますか?その場合、サブスクライブされたプロセスのpidを登録するには小さな共有メモリが必要ですが、それはそれ自体の問題のセットをもたらすようです。 1つのプロセスがクラッシュしたり応答しなかったりするとどうなりますか? ....
いくつかの文脈を与える。他のすべてのプロセスが共有メモリの場所から読み込むべき新しい状態を公開しました。一度に複数の更新が発生した場合でも1つの更新を見逃しても問題ありませんが、プロセスは少なくとも最新の最新の値を読み取る必要があります。私はタイムアウトでポーリングすることができましたが、それは正しい解決策ではないようです。
現在、私は、.NET 4.0以来ダウン
ChangeEvent = new EventWaitHandle(false, EventResetMode.ManualReset, counterName + "_Event");
ChangeEvent.Set();
Thread.Sleep(1); // increase odds to release all waiters
ChangeEvent.Reset();
これは私が思い付くことができるすべての競争条件を解決する非常に良い解決策です。ありがとう! –