SemaphoreSlim 클래스를 사용하면 비동기에서 lock을 사용할 수 있다.
AsyncLock.cs
namespace Common;
public sealed class AsyncLock
{
// 한번에 하나의 스레드만 접근 가능하도록 설정되어, 사실상 뮤텍스처럼 동작한다.
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
// 동시 실행 제한 수 3
//private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(3);
public async Task<IDisposable> LockAsync()
{
await _semaphore.WaitAsync();
return new Handler(_semaphore);
}
private sealed class Handler : IDisposable
{
private readonly SemaphoreSlim _semaphore;
private bool _disposed = false;
public Handler(SemaphoreSlim semaphore)
{
_semaphore = semaphore;
}
public void Dispose()
{
if (_disposed == false)
{
_semaphore.Release();
_disposed = true;
}
}
}
}
사용 방법 ↓
private readonly AsyncLock _AsyncLock = new AsyncLock();
public async Task TestAsyncLock()
{
using (await _AsyncLock.LockAsync())
{
await 뭔가 작업
}
}
IDisposable을 상속받는 Handler 클래스로 처리하기 때문에 별도의 관리가 필요 없다.
참고)