C#の.NET 3.5:イベントハンドラを起動し、それが完了するまで待機する方法
-
06-09-2019 - |
質問
私は、ループ内のキューからデータを受信ワーカースレッドを含むクラスを持っています。
アプリケーションの別の部分は、クラスが各キュー項目に上昇させる、このクラスからイベントをシンクします。
これらのイベントは非同期に解雇されているので、忙しい時期にアプリの他の部分は、一度に複数のイベントを処理することができます。
これは問題ないはずですが、我々は、これが問題を引き起こす可能性がシナリオを発見した。
主な問題に対処しますながら私たちは、迅速な解決を必要としています。フレームワークは、私は各イベントが処理されます(そう、彼らは順番に処理されている)間、待機するようにワーカースレッドを強制することができます簡単な方法を提供していますか?ない場合は、これを実装する最も簡単な方法は何ですか?
解決
単純な答えは、イベントハンドラで単一のオブジェクト上)(ロックするだろう。 theadsのすべてがロックを取得するために待機していました。
他のヒント
ManualResetEventクラス、ここであなたを助けるかもしれません。最後の1が完了するまでは、次のイベントの発射を阻止するために使用することができます。
私の推測では、あなたは、単にイベントを高め、直接メソッドを呼び出すことによってアクションをトリガから離れて行きたいということです。
私の知る限りのイベントは非同期であることを行っていると私はそれを変更するのいずれかの「簡単」な方法を認識していないです。
は、別の答えがあると判明します。あなただけのメソッドに次の属性を追加することができます。
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
という一般的な方法はありません。
最後にハンドラを追跡するためのメカニズムを提供する必要があります。
をあなたはBeginInvokeメソッドを使用して、直接ではなく、イベントを上げている場合、あなたは、同期実際のイベントハンドラを呼び出して非同期ラッパーを上げ、その中のラッパーを使用することができます。ラッパーは(インタロック操作で)カウンタを維持するか、あなたのニーズを満たしているとして、イベントを設定することができます。
のような何かます:
TheDelegate realHandler = theEvent;
var outer = this;
ThreadPool.QuereUserWorkItem(x => {
// Set start of handler
realHandler(outer, eventArgs);
// Set handler finished
};
キュー読み取りワーカースレッドで発生したイベントをシンクするイベントハンドラのすべてがキュー読み取りワーカースレッドで呼び出されます。イベントハンドラは、独自のスレッドを生成していない限り、あなたはキュー読み取りワーカースレッド上でThread.Join()を呼び出すことによって終了するイベントハンドラを待つことができる必要があります。