public class LockableObject { private readonly SemaphoreSlim asyncLock = new SemaphoreSlim(1); /// /// Gets a lock on this object. /// /// The token. /// A disposable which release the lock. public Task GetLock(CancellationToken token) { return this.asyncLock.WaitAsync(token).ContinueWith(result => { if (result.IsCompleted && !result.IsFaulted && !result.IsFaulted) { return Disposable.Create(() => asyncLock.Release()); } throw result.Exception?.InnerExceptions.FirstOrDefault() ?? result.Exception ?? new Exception("Failed to aquire the lock for an unknown reason."); }); } }