以下は、私の問題を示すメソッド「SomeMethod」を持つクラスです。
class SomeClass
{
AutoResetEvent theEvent = new AutoResetEvent(false);
// more member declarations
public void SomeMethod()
{
// some code
theEvent.WaitOne();
// more code
}
}
このメソッドはスレッドセーフになるように設計されており、異なるスレッドで呼び出されます。ここで私の質問は、いつでも「theEvent」オブジェクトで「WaitOne」メソッドを呼び出したすべてのスレッドのブロックを解除する方法です。マルチスレッド プログラムを正常に停止および開始できるようにする必要があるため、この要件は私の設計で頻繁に発生します。マルチスレッド プログラムを開始するのはかなり簡単ですが、停止するのは難しいように思えます。
これが私がこれまでに試したもので、明らかにうまくいきます。しかし、これは標準的なアプローチですか?
public void UnblockAll()
{
do
{
theEvent.Set();
} while (theEvent.WaitOne(0));
}
「UnblockAll」メソッドは、「SomeClass」クラスのメンバーです。ここで使用する手法は、WaitOne メソッドの MSDN ドキュメントに基づいています。以下のドキュメントの関連部分を引用しています。
millisecondsTimeout がゼロの場合、メソッドはブロックされません。待機ハンドルの状態をテストし、すぐに戻ります。
do..while ループでSet メソッドを呼び出します。これにより、WaitOne メソッド (「SomeMethod」メソッド内にコード化されている) への呼び出しが原因でブロックされた可能性がある単一のスレッドが解放されます。次に、'theEvent' オブジェクトの状態をテストして、シグナル状態かどうかを確認します。このテストは、タイムアウト パラメータを受け取る WaitOne メソッドのオーバーロードされたバージョンを呼び出すことによって行われます。WaitOne メソッドを呼び出すときに使用する引数はゼロです。ドキュメントによると、呼び出しはブール値ですぐに返されます。戻り値が true の場合、「theEvent」オブジェクトはシグナル状態です。「SomeMethod」メソッドの「WaitOne」メソッドの呼び出しで少なくとも 1 つのスレッドがブロックされていた場合、「Set」メソッド (「UnblockAll」メソッド内にコード化されている) の呼び出しによってブロックが解除されます。したがって、'UnblockAll' メソッドの do..while ステートメントの最後にある 'WaitOne' メソッドの呼び出しは false を返します。ブロックされたスレッドがない場合にのみ、戻り値は true になります。
上記の推論は正しいですか? また、正しい場合、その手法は私の問題に対処するための標準的な方法ですか? 主に .net コンパクト フレームワーク 2.0 プラットフォームでソリューションを使用しようとしています。