pincur
pincur

Reputation: 21

.NET 4.5 Semaphore WaitOne(0) doesn't block, but decrements semaphore count

Up to the documentation of .NET 4.5 if I use WaitOne(Int32) method on some object of Semaphore class (or - generally - WaitHandle class) with 0 (zero) as its argument, it doesn't block and may be used for testing semaphore's current state:

"If millisecondsTimeout is zero, the method does not block. It tests the state of the wait handle and returns immediately."

To me it's highly confusing (or even misleading), because it doesn't block, but it decrements semaphore count by one. So if I use it like this:

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

then it may decrement my semaphore (if true), causing other threads to be unable to run. So we cannot use it like this for only testing semaphore's state. The correct use should be

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

So it doesn't only test semaphore's state! Am I right?

Upvotes: 0

Views: 2258

Answers (1)

Scott Chamberlain
Scott Chamberlain

Reputation: 127543

Correct, it does not only test the semaphore state, a better wording would be

If millisecondsTimeout is zero, the method does not block. The method attempts to take a wait handle and returns immediately with the success or failure of that attempt.

Also your example is incorrect, correct way to use this would be

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.
}

You should only call mySemaphore.Release() when mySemaphore.WaitOne returns true, in your current example you are calling it only when it returns false.

Upvotes: 7

Related Questions