-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAsyncLock.cs
35 lines (28 loc) · 1.11 KB
/
AsyncLock.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
namespace VLink.Private.GrpcRoomServer;
public class AsyncLock {
private readonly Task<IDisposable> _releaserTask;
private readonly SemaphoreSlim _semaphore = new(1, 1);
private readonly IDisposable _releaser;
public AsyncLock() {
_releaser = new Releaser(_semaphore);
_releaserTask = Task.FromResult(_releaser);
}
/// <summary>Use inside 'using' block</summary>
public IDisposable Lock() {
_semaphore.Wait();
return _releaser;
}
/// <summary>Use inside 'using' block with await</summary>
public Task<IDisposable> LockAsync() {
Task task = _semaphore.WaitAsync();
return !task.IsCompleted
? task.ContinueWith((Func<Task, object, IDisposable>) ((_, releaser) => (IDisposable) releaser), _releaser,
CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default)
: _releaserTask;
}
private class Releaser : IDisposable {
private readonly SemaphoreSlim _semaphore;
public Releaser(SemaphoreSlim semaphore) => _semaphore = semaphore;
public void Dispose() => _semaphore.Release();
}
}