neosmart / AsyncLock

An async/await-friendly lock for .NET, complete with asynchronous waits, safe reëntrance, and more.
https://neosmart.net/blog/2017/asynclock-an-asyncawait-friendly-locking-library-for-c-and-net/
MIT License
193 stars 28 forks source link

Support cancellation token for synchronous lock method #9

Closed Stroniax closed 3 years ago

Stroniax commented 3 years ago

Since the synchronous Lock method is calling _parent.Wait(), which accepts a cancellation token, please allow a cancellation token to be provided to the Lock() method.

https://github.com/neosmart/AsyncLock/blob/653b788cdd8a17c6e3615a5675b57093ffb01454/AsyncLock/AsyncLock.cs#L81-L89

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

https://github.com/neosmart/AsyncLock/blob/653b788cdd8a17c6e3615a5675b57093ffb01454/AsyncLock/AsyncLock.cs#L205-L212

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.

mqudsi commented 3 years ago

Sure, this should be possible. We’re already supporting CancellationToken for the async code, so this would look very similar. Feel free to open a PR.

mqudsi commented 2 years ago

This is included in today's non-preview AsyncLock 3.2.0 release on NuGet. @Stroniax you are mentioned in the release notes for your contribution - much appreciated!