Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 985
Romasz Avatar asked Apr 18 '14 11:04

Romasz


1 Answers

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.

like image 90
usr Avatar answered Oct 05 '22 17:10

usr