编辑:我甚至想提出这个问题暂时疯狂,但当时有意义(见下面的编辑2).
对于.NET 3.5项目,我有两种类型的资源(R1和R2),我需要检查它的可用性.每种资源类型可以随时(例如)有10个实例.
当其中一种资源可用时,我的工作线程需要唤醒(存在可变数量的线程).在早期的实现中,只有一种资源类型,我使用Semaphore来检查可用性.
现在我需要等待两个单独的信号量(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();
}
Run Code Online (Sandbox Code Playgroud)
然而,这有一个问题.从MSDN文档WaitAny:
如果在调用期间发出多个对象的信号,则返回值是具有所有信号通知对象的索引值最小的信号通知对象的数组索引.
这表明我可能会在打电话后将我的信号量计数减少1 WaitAny.因为signalledHandle将指示s1已发出信号,我将开始使用资源R1,并在完成后释放它.但是,由于我不知道S2是否已发出信号,因此此资源的可用性计数现在可能已关闭.如果发生这种情况10次,我的信号量将永久"空",资源R2将不再使用.
处理这个问题的最佳方法是什么?我是否应该从使用两个信号量切换到简单计数器,并在任何一个计数器更改时发出AutoResetEvent信号?我错过了一些更优雅的方法吗?
编辑1:
根据Ravadre的说法,之后只有一个信号量会被改变WaitAny.略微修改他的例子似乎证实了这一点,但有没有人可以指出我指出这个的一些官方文件?
编辑2:
我在回家的路上想着这个.只有这样,我才意识到,WaitAny任何用途都必须如此.这个问题不仅限于信号量,而是几乎任何类型的同步对象,WaitAny几乎没用.