Named Mutex with await
You must ensure that mutex is being accessed consistently on a certain thread. You could do that in a number of ways:
- Do not use await in the critical section during which you hold the mutex
- Invoke the mutex calls on a
TaskScheduler
that only has a single thread
That could look like this:
await Task.Factory.StartNew(() => mutex.WaitOne(), myCustomTaskScheduler);
Or, you use synchronous code and move everything to the thread-pool. If you only have access to an async version of DoSomething
, consider just calling Task.Wait
on its result. You'll suffer a minor inefficiency here. Probably fine.
I use named Mutex in async method to control that only one process call it. Another process checks for named Mutex and exits if it cannot create new named Mutex.
I can use named Mutex in async method as OS guarantees/controls only one instance of named object in OS. Plus, I do not use WaitOne/Release that should be called on the thread.
public async Task<bool> MutexWithAsync()
{
// Create OS-wide named object. (It will not use WaitOne/Release)
using (Mutex myMutex = new Mutex(false, "My mutex Name", out var owned))
{
if (owned)
{
// New named-object was created. We own it.
try
{
await DoSomething();
return true;
}
catch
{
return false;
}
}
else
{
// The mutex was created by another process.
// Exit this instance of process.
}
}
}