Edit:我想说这个问题只是暂时的精神错乱,但当时这是有道理的(见下面的编辑2)。
对于 .NET 3.5 项目,我有两种类型的资源(R1 and R2)我需要检查其可用性。每种资源类型在任何时候都可以有(比如说)10 个实例。
当任一类型的资源可用时,我的工作线程需要唤醒(线程数量可变)。在早期的实现中,只有一种资源类型,我使用信号量来检查可用性。
现在我需要等待两个单独的信号量(S1 and 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();
}
然而,这有一个问题。来自 MSDN 文档WaitAny
:
如果多个对象变成
在通话过程中发出信号,返回
value 是数组索引
具有最小信号的对象
所有信号的索引值
对象。
这表明我在调用后可能将两个信号量计数都减少了 1WaitAny
。因为signalledHandle
将表明 s1 已收到信号,我将开始使用资源R1,并在完成后释放它。然而,由于我不知道是否S2无论是否发出信号,该资源的可用性计数现在可能已关闭。如果这种情况发生 10 次,我的信号量将永久“空”并且资源R2将不再被使用。
处理这个问题的最佳方法是什么?我是否应该从使用两个信号量切换到简单计数器,并在任一计数器发生更改时使用 AutoResetEvent 发出信号?我错过了一些更优雅的方法吗?
Edit 1:
根据 Ravadre 的说法,只有一个信号量在之后实际上会被改变WaitAny
。稍微修改他的示例似乎证实了这一点,但是有没有人可以向我指出一些指定这一点的官方文档?
Edit 2:
我在回家的路上思考着这个问题。直到那时我才意识到这一定是真的WaitAny
有任何用处。这个问题不限于信号量,而是任何类型的同步对象,使得WaitAny
实际上没用。