patterncsharpModerate
Implementing an asynchronous mutex in C#
Viewed 0 times
asynchronousimplementingmutex
Problem
I wrote a simple synchronization primitive that I can use with async operations on an external REST service so that I don't call it twice from different threads and have one call fail due to not having the latest state. Despite obvious limitations of that design decision I think this should solve my problem...
Of course this is a hack... did I just overlook a better way to do this using the standard framework?
struct DumbAsyncMutex
{
int busy;
public async Task WithMutexAsync(Func t)
{
while (Interlocked.CompareExchange(ref busy, 1, 0) != 0)
{
await Task.Delay(100);
}
try
{
await t();
}
finally
{
while (Interlocked.CompareExchange(ref busy, 0, 1) != 1)
{
throw new Exception("Releasing the mutex failed - but this should never happen");
}
}
}
}Of course this is a hack... did I just overlook a better way to do this using the standard framework?
Solution
A better alternative to the busy wait loop would be to use a Semaphore - in this case a
The advantage is that it has
SemaphoreSlim would probably be the most appropriate. Semaphores are not reentrant. This would simplify the implementation to:struct DumbAsyncMutex
{
private SemaphoreSlim _Semaphore = new SemaphoreSlim(1, 1);
public async Task WithMutexAsync(Func t)
{
await _Semaphore.WaitAsync();
try
{
await t();
}
finally
{
_Semaphore.Release(1);
}
}
}The advantage is that it has
async support and you can abandon the waiting by using cancellation tokens.Code Snippets
struct DumbAsyncMutex
{
private SemaphoreSlim _Semaphore = new SemaphoreSlim(1, 1);
public async Task WithMutexAsync(Func<Task> t)
{
await _Semaphore.WaitAsync();
try
{
await t();
}
finally
{
_Semaphore.Release(1);
}
}
}Context
StackExchange Code Review Q#115836, answer score: 13
Revisions (0)
No revisions yet.