2014-11-04 51 views
0

如果我在Semaphore类的某个对象上使用WaitOne(Int32)方法(或 - 一般为 - WaitHandle类),直到.NET 4.5的documentation以0(零)作为参数,它不会阻塞并且可以用于测试信号量的当前状态:.NET 4.5信号量WaitOne(0)不会阻塞,但会减少信号计数

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

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

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

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

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

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

+2

简单的测试,而不递减是没有意义的,因为你得到的答案是立即过时和无用的,因为毕竟它已被写入供您阅读一些其他的线程可以更改答案,但你读过它。 – GSerg 2014-11-04 15:39:09

+2

@CodeCaster无视,我只是愚蠢的。 – decPL 2014-11-04 15:48:23

+0

好吧,我可以同意,但是...想象一下,反转的情况 - 当WaitOne(0)结果为真时 - 它不会改变信号量的状态,结果是没用的,同时另一个线程可能释放信号量。 – pincur 2014-11-04 15:50:50

回答

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

+0

你是对的,它应该DoSomething()当mySemaphore.WaitOne(0)返回true,我刚刚编辑我的帖子。 Try..finally部分提醒+1 – pincur 2014-11-04 15:53:50