I have a critical section of code that should be run by only one process at a time. To ensure only one process on the machine is ever running this critical block I use a global Mutex. The code in the critical section uses async/await. Overall the code looks something like this:
var mutex = new Mutex(false, @"Global\MyMutexName");
mutex.WaitOne(-1, false);
SetupASystemWideResource()
await DoSomeAsyncWorkOnThatResource();
mutex.ReleaseMutex();
The issue is that the code after the await can happen on a different thread. So the mutex could get released on a different thread than it was acquired. This causes an exception
System.ApplicationException: Object synchronization method was called from an unsynchronized block of code.
Normally this would make since you dont want a different thread releasing the mutex than acquiring it. However in my case I am really only interested in preventing a 2nd instance of the application from setting up the system resource in a different way while the first instance is using it. The resource itself is fine to be used from multiple threads within the one instance.
What is the correct way to ensure this and also do the work asynchronously?
If i understand the problem, and this is a console app or there is no synchronisation context, just call Wait
, there is no fear of a deadlock and it should work fine
var mutex = new Mutex(false, @"Global\MyMutexName");
mutex.WaitOne(-1, false);
DoSomeAsyncWorkOnThatResource().Wait();
mutex.ReleaseMutex();
Or if you really must (and more controversially) you could use
Task.Run(async () => await DoSomeAsyncWorkOnThatResource()).Wait();
The other thing you can do is use a custom Scheduler like CurrentThreadTaskScheduler
(first time i have seen you use for it), as described in Stephen Toubs Parallel Programming with .NET. Nuget ParallelExtensionsExtras
runs all tasks on the current thread when scheduling is requested
And use it with Task.Factory.StartNew
or something that takes a scheduler
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With