BatteryBackupUnit
BatteryBackupUnit

Reputation: 13233

Is Wait()-ing on a ManualResetEventSlim guaranteed to throw on cancellation?

Given the following code:

CancellationTokenSource cts = new CancellationTokenSource();
ManualResetEventSlim mre = new ManualResetEventSlim();

and these two threads executing concurrently:

mre.Wait(cts.Token);

cts.Cancel();
mre.Set();

is the first one (call to mre.Wait(cts.Token)) guaranteed to throw an OperationCanceledException or is it also possible that it will just return?

My gut says I should expect either to happen (internal race condition). MSDN does not give an answer, it just says "while observing the CancellationToken".

I'm hoping for an answer with specific details as to how and why.

I would like to pre-empt comments like "you should expect Cancel() and Set() to occur concurrently / in any order, and thus both cases, anyway". I'm fully aware of that.

Upvotes: 3

Views: 809

Answers (1)

Evk
Evk

Reputation: 101483

There is race condition because Wait is implemented like that:

public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken)
{
    ThrowIfDisposed();
    cancellationToken.ThrowIfCancellationRequested(); // an early convenience check

    if (millisecondsTimeout < -1)
    {
        throw new ArgumentOutOfRangeException("millisecondsTimeout");
    }

    if (!IsSet)
    {
    // lots of stuff here, not relevant
    }
    return true;
}

Second thread (which both cancels and sets the token) might interrupt first thread right between cancellationToken.ThrowIfCancellationRequested() check and IsSet check.

Upvotes: 2

Related Questions