internal IDisposable ObtainLock(CancellationToken cancellationToken)
{
while (!TryEnter())
{
// We need to wait for someone to leave the lock before trying again.
_parent._retry.Wait(cancellationToken);
}
return this;
}
public IDisposable Lock(CancellationToken cancellationToken = default)
{
var @lock = new InnerLock(this, _asyncId.Value, ThreadId);
// Increment the async stack counter to prevent a child task from getting
// the lock at the same time as a child thread.
_asyncId.Value = Interlocked.Increment(ref AsyncLock.AsyncStackCounter);
return @lock.ObtainLock(cancellationToken);
}
I haven't looked very much at the code, I imagine proper disposal may also be required if the cancellation is requested.