【发布时间】:2009-08-19 13:51:38
【问题描述】:
编辑:我想为自己提出这个问题表示暂时的精神错乱,但当时这是有道理的(见下面的编辑 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();
}
然而,这有一个问题。来自WaitAny 上的 MSDN 文档:
如果不止一个对象变成 在通话期间发出信号,返回 value 是数组的索引 具有最小信号的对象 所有信号的索引值 对象。
这表明在调用 WaitAny 后,我可能将两个信号量计数都减少了 1。因为signalledHandle 将表明s1 已发出信号,所以我将开始使用资源R1,并在完成后释放它。但是,由于我不知道是否已发出 S2 信号,因此该资源的可用性计数现在可能已关闭。如果这种情况发生 10 次,我的信号量将永久“空”,并且资源 R2 将不再使用。
解决这个问题的最佳方法是什么?我应该从使用两个信号量切换到简单的计数器和 AutoResetEvent 以在任一计数器更改时发出信号吗?我错过了一些更优雅的方法吗?
编辑 1:
根据 Ravadre 的说法,在WaitAny 之后,实际上只有一个信号量会被更改。稍微修改他的例子似乎证实了这一点,但是有没有人可以指出我的一些官方文档指定这一点?
编辑 2:
我在回家的路上一直在思考这个问题。直到那时我才意识到WaitAny 必须是这样才能有任何用处。这个问题不仅限于信号量,而是几乎任何类型的同步对象,使WaitAny 实际上毫无用处。
【问题讨论】:
-
我添加了一个有价值的(虽然不是官方的)来源,您可能想要查看。
标签: c# .net multithreading waithandle