I'm accessing an EventStore from a dotnet core web application. There is a single connection shared by all threads. The connection is opened on first access and I need to ensure only one thread opens the connection. Previously I would have used a lock
but then I can't await
the method to open the connection.
I found the following snippet of code that looks like it should do the trick:
public class AsyncLock : IDisposable
{
private readonly SemaphoreSlim _semaphoreSlim = new SemaphoreSlim(1, 1);
public async Task<AsyncLock> LockAsync()
{
await _semaphoreSlim.WaitAsync().ConfigureAwait(false);
return this;
}
public void Dispose()
{
_semaphoreSlim.Release();
}
}
And use it in my code:
private static readonly AsyncLock _mutex = new AsyncLock();
private volatile bool _isConnected = false;
private async Task EstablishConnected()
{
if (!_isConnected)
{
using (await _mutex.LockAsync())
{
if (!_isConnected)
{
await _connection.ConnectAsync().ConfigureAwait(false);
_isConnected = true;
}
}
}
}
Is this a reasonable approach to synchronising access to initialise/open the connection to the EventStore?
Turns out there is a useful nuget library and associated Github repo from Stephen Cleary that is a drop in replacement for the AsyncLock
class above.