2014-11-04 50 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