.NET 4.5 Semaphore WaitOne(0)没有';t块,但递减信号量计数

本文关键字:信号量 WaitOne Semaphore 没有 NET | 更新日期: 2023-09-27 18:29:09

根据.NET 4.5的文档,如果我在Semaphore类(或通常是WaitHandle类)的某个对象上使用WaitOne(Int32)方法,并以0(零)为参数,它不会阻塞,可以用于测试信号量的当前状态:

如果毫秒超时为零,该方法不会阻塞。它测试等待句柄的状态并立即返回。

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

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

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

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

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

.NET 4.5 Semaphore WaitOne(0)没有';t块,但递减信号量计数

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

如果毫秒超时为零,则该方法不会阻塞。该方法尝试获取等待句柄,并在尝试成功或失败时立即返回。

同样,你的例子是不正确的,正确的使用方法是

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.WaitOne返回true时调用mySemaphore.Release(),在当前示例中,您只在它返回false时调用它。