Search code examples
c#multithreadingasynchronousasync-await

Named Mutex with await


Hence I can't use thread-affine locks with async - how can I guard my resources when running multiple processes?

For example I've two processes that use a Task below:

 public async Task<bool> MutexWithAsync()
 {
     using (Mutex myMutex = new Mutex(false, "My mutex Name"))
     {
         try
         {
             myMutex.WaitOne();
             await DoSomething();
             return true;
         }
         catch { return false; }
         finally { myMutex.ReleaseMutex(); }
     }
 }

If the method guarded by a Mutex is synchronous then above code will work but with async I will get:

Object synchronization method was called from an unsynchronized block of code.

So is Named Mutex useless with asynchronous code?


Solution

  • You must ensure that mutex is being accessed consistently on a certain thread. You could do that in a number of ways:

    1. Do not use await in the critical section during which you hold the mutex
    2. 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.