Improve exception handling of AsyncLock.

This commit is contained in:
Christian Kratky
2020-10-30 00:19:57 +01:00
parent f9630ef347
commit 05101f0e0e
+22 -8
View File
@@ -7,9 +7,11 @@ namespace MQTTnet.Internal
// From Stephen Toub (https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/) // From Stephen Toub (https://blogs.msdn.microsoft.com/pfxteam/2012/02/12/building-async-coordination-primitives-part-6-asynclock/)
public sealed class AsyncLock : IDisposable public sealed class AsyncLock : IDisposable
{ {
readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); readonly object _syncRoot = new object();
readonly Task<IDisposable> _releaser; readonly Task<IDisposable> _releaser;
SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
public AsyncLock() public AsyncLock()
{ {
_releaser = Task.FromResult((IDisposable)new Releaser(this)); _releaser = Task.FromResult((IDisposable)new Releaser(this));
@@ -36,21 +38,33 @@ namespace MQTTnet.Internal
public void Dispose() public void Dispose()
{ {
_semaphore?.Dispose(); lock (_syncRoot)
{
_semaphore?.Dispose();
_semaphore = null;
}
} }
class Releaser : IDisposable internal void Release()
{ {
readonly AsyncLock _toRelease; lock (_syncRoot)
internal Releaser(AsyncLock toRelease)
{ {
_toRelease = toRelease; _semaphore?.Release();
}
}
sealed class Releaser : IDisposable
{
readonly AsyncLock _lock;
internal Releaser(AsyncLock @lock)
{
_lock = @lock;
} }
public void Dispose() public void Dispose()
{ {
_toRelease._semaphore.Release(); _lock.Release();
} }
} }
} }