编辑: 我想为自己的问题辩解一下,现在看来可能有点荒唐,但是当时真的很有道理(参见下面的编辑 2)。
对于一个 .NET 3.5 项目,我有两种类型的资源(R1 和 R2>),需要检查它们的可用性。每种资源类型最多同时可以有10个实例。
当其中任何一种类型的资源变得可用时,我的工作线程需要唤醒(有可变数量的线程)。在早期的实现中,只有一种资源类型,我使用了一个信号量来检查可用性。
现在我需要等待两个分别跟踪资源可用性的信号量 (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();
}
然而,这里有一个问题。根据MSDN关于
WaitAny
的文档:如果在调用期间有多个对象变为信号状态,则返回值是所有已发出信号对象中索引值最小的信号对象的数组索引。
这表明在调用
WaitAny
之后,我可能会将两个Semaphore计数都减少1。因为signalledHandle
会指示s1被标记,所以我将开始使用资源R1,并在完成后释放它。但是,由于我不知道是否标记了S2,因此该资源的可用计数现在可能不正确。如果这种情况发生10次,我的信号量将永久处于“空”状态,且资源R2将不再使用。如何处理这种情况?应该切换到使用简单计数器和AutoResetEvent来信号任一计数器更改吗?我是否错过了一些更优雅的方法?
编辑1:根据Ravadre的说法,在
WaitAny
之后只有一个Semaphore实际上会被更改。稍微修改他的示例似乎证实了这一点,但是否有人可以指向某些官方文档来指定这一点?编辑2:我在回家的路上想到了这个问题。只有那时我意识到这对于
WaitAny
才有意义。这个问题不仅限于信号量,而是适用于几乎任何类型的同步对象,使得WaitAny
实际上没有用处。