AsyncLock

 1.AsyncLock

public sealed class AsyncLock : IDisposable, IAsyncDisposable
{
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(initialCount: 1, maxCount: 1);

public async Task<IDisposable> LockAsync(CancellationToken cancellationToken = default)
{
await _semaphore.WaitAsync(cancellationToken)
.ConfigureAwait(continueOnCapturedContext: false);

return new DisposeAction(() => _semaphore.Release());
}

public void Dispose() => _semaphore.Dispose();

public async ValueTask<IAsyncDisposable> AcquireAsync(CancellationToken cancellationToken = default)
{
await _semaphore.WaitAsync(cancellationToken)
.ConfigureAwait(continueOnCapturedContext: false);

return new AsyncDisposeAction(() => _semaphore.Release());
}

public ValueTask DisposeAsync()
{
_semaphore.Dispose();

return ValueTask.CompletedTask;
}
}

 2.DisposeAction

public struct DisposeAction : IDisposable
{
private bool _isDisposed;
private Action _action;

public DisposeAction(Action action)
{
_isDisposed = false;
_action = action;
}

public void Dispose()
{
if (_isDisposed)
{
return;
}

_isDisposed = true;
_action();
}
}

 3.AsyncDisposeAction

public struct AsyncDisposeAction : IAsyncDisposable
{
private bool _isDisposed;
private Action _action;

public AsyncDisposeAction(Action action)
{
_isDisposed = false;
_action = action;
}

public ValueTask DisposeAsync()
{
if (_isDisposed)
{
return ValueTask.CompletedTask;
}

_isDisposed = true;

_action();

return ValueTask.CompletedTask;
}
}

4.使用

 await await _connectLock.AcquireAsync();

 await using (await _connectLock.AcquireAsync()){};

posted @ 2022-05-03 13:57  二杆  阅读(260)  评论(0)    收藏  举报