-
Notifications
You must be signed in to change notification settings - Fork 1
AsyncMutex
Serves as an exclusive lock for TPL like code. Assume that using a "traditional" mutex would look like this:
private static List<int> _commonData = new List<int>();
private static object _mutex = new object();
public static void Run()
{
lock(_mutex)
{
// access common data
_commonData.Add(42);
}
}
Any object can serve as mutex. When you write a "sensitive" block, you wrap it with lock(_mutex)
and the thread will be blocked as long as the _mutex is not free. Once it is released, the thread will be released, and the code will continue to run, and the _mutex will be owned by the local thread. Of course, you wont be able to run code with async await
inside that block, and again You will be blocking the thread so if the thread you are running in is the main thread, you will be freezing the UI.
The async version of the same code will look like this:
private static List<int> _commonData = new List<int>();
private static AsyncMutex _asyncMutex = new AsyncMutex();
public static async Task RunAsync()
{
using (await _asyncMutex.Lock())
{
_commonData.Add(42);
}
}
Note the use of using() {}
, the Lock
method returns an IDisposable
releases the lock when it is disposed. Note also that the wait for the lock itself is done using await
, so that the thread is released while the lock is busy, until it is free, and then the code continues to run in the same synchronization context, but no necessarily on the same thread.