編集:この質問をすることさえ一時的な狂気を認めたいと思いますが、当時は理にかなっていました(以下の編集2を参照)。
.NET 3.5 プロジェクトの場合、2 種類のリソース ( R1とR2 ) が利用可能かどうかを確認する必要があります。各リソース タイプは、いつでも (たとえば) 10 個のインスタンスを持つことができます。
いずれかのタイプのリソースが利用可能になったら、ワーカー スレッドを起動する必要があります (スレッドの数は可変です)。以前の実装では、リソースの種類は 1 つしかなく、セマフォを使用して可用性を確認していました。
ここで、リソースの可用性を追跡する 2 つの別個のセマフォ ( S1とS2 ) を待機する必要があります。
WaitHandle[] waitHandles = new WaitHandle[] { s1, s2 };
int signalledHandle = WaitHandle.WaitAny(waitHandles);
switch (signalledHandle)
{
case 0:
// Do stuff
s1.Release();
case 1:
// Do stuff
s2.Release();
}
ただし、これには 1 つの問題があります。次の MSDN ドキュメントからWaitAny
:
呼び出し中に複数のオブジェクトがシグナル状態になった場合、戻り値は、すべてのシグナル状態のオブジェクトの中で最小のインデックス値を持つシグナル状態のオブジェクトの配列インデックスです。
これは、 を呼び出した後、両方のセマフォ カウントを 1 減らした可能性があることを示唆していWaitAny
ます。signalledHandle
s1 が通知されたことを示すため、リソースR1の使用を開始し、完了したら解放します。ただし、 S2が通知されたかどうかがわからないため、このリソースの可用性カウントはオフになっている可能性があります。これが 10 回発生すると、私のセマフォは永久に「空」になり、リソースR2はまったく使用されなくなります。
これに対処する最善の方法は何ですか?2 つのセマフォを単純なカウンターと AutoResetEvent の使用に切り替えて、いずれかのカウンターが変更されたときに通知する必要がありますか? もっとエレガントなアプローチが欠けていますか?
編集 1:
Ravadre によると、セマフォの 1 つだけが実際に変更されWaitAny
ます。彼の例を少し変更するとこれが確認されるようですが、これを指定している公式ドキュメントを教えてくれる人はいますか?
編集 2:
帰り道にこれについて考えていました。その時初めて、これが何の役にも立たないということに気がつきましたWaitAny
。この問題はセマフォに限定されるものではなく、ほぼすべてのタイプの同期オブジェクトで発生し、WaitAny
実質的に役に立たなくなります。