3using System.Threading.Tasks;
10 public sealed
class AsyncLock : IDisposable, IAsyncDisposable
12 private readonly SemaphoreSlim semaphore =
new(1, 1);
13 private bool disposed;
19 public async ValueTask<Releaser>
LockAsync(CancellationToken cancellationToken =
default)
21 await this.semaphore.WaitAsync(cancellationToken).ConfigureAwait(
false);
28 public sealed
class Releaser : IDisposable, IAsyncDisposable
34 AsyncLock? O = Interlocked.Exchange(ref this.owner,
null);
35 if (O is not
null && !O.disposed)
37 O.semaphore.Release();
40 public ValueTask DisposeAsync()
43 return ValueTask.CompletedTask;
49 if (this.disposed)
return;
51 this.semaphore.Dispose();
54 public ValueTask DisposeAsync()
57 return ValueTask.CompletedTask;
Disposable releaser. Class (not struct) to avoid double-release via accidental copies.
Simple async-exclusive lock (lightweight). Each call to LockAsync yields a disposable releaser that m...
async ValueTask< Releaser > LockAsync(CancellationToken cancellationToken=default)
Acquires the lock asynchronously, returning a disposable releaser that must be disposed exactly once.