.NET 4.5信号量WaitOne(0)不会阻塞,但会减少信号量计数

时间:2014-11-04 15:31:49

标签: c# .net

如果我在Semaphore类的某个对象(或 - 通常 - WaitHandle类)上使用WaitOne(Int32)方法,并以0(零)作为参数,那么最高为.NET 4.5的documentation,它不会阻止并可用于测试信号量的当前状态:

“如果millisecondsTimeout为零,则该方法不会阻塞。它会测试等待句柄的状态并立即返回。”

对我而言,它非常令人困惑(甚至误导),因为它不会阻塞,但它会将信号量减少一个。所以,如果我这样使用它:

If (!mySemaphore.WaitOne(0)) DoSomething();

然后它可能会减少我的信号量(如果为true),导致其他线程无法运行。所以我们不能像这样只用它来测试信号量的状态。正确的用法应该是

If (!mySemaphore.WaitOne(0)) DoSomething();
Else mySemaphore.Release();

所以它不仅测试信号量的状态!我是对的吗?

1 个答案:

答案 0 :(得分:7)

正确,它不仅测试信号量状态,更好的措辞

  

如果millisecondsTimeout为零,则该方法不会阻止。该方法尝试使用等待句柄并立即返回该尝试的成功或失败。

此外,您的示例不正确,使用此方法的正确方法是

if (mySemaphore.WaitOne(0)) 
{
    try
    {
        DoSomething();
    }
    finally
    {
        //Only call release when WaitOne returns true, also put it in a finally 
        //block to make sure it always gets called.
        mySemaphore.Release();
    }
}
else
{
    //Do something else because the resource was not available.
}

你应该只在mySemaphore.Release()返回true时调用mySemaphore.WaitOne,在你当前的例子中,只有当它返回false时才调用它。