65.9K
CodeProject is changing. Read more.
Home

Calling async Function Inside lock Block

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (4 votes)

May 19, 2016

CPOL
viewsIcon

24611

Calling async function inside lock block

Why

Sometimes, you just want to execute an async call inside a lock statement.

By default, you cannot accomplish this functionality, the compiler will get really mad at you because you are trying to create context-switching inside a lock.

I'm not saying that this is the cleanest software design that I could think of, but if you want – you can!

How

Here is how you can work around this issue:

In the below functions, you can notice that they use ManualResetEvent, it gives them the ability to wait inside the lock statement although the context-switching. We are simply waiting for the event.

*If your Func throws exception, you will not get in outer try-catch, you need to be aware of it.

Code

public static Task Execute(object lockObject, Func<Task> func)
{
    return Task.Run(() =>
    {
        ManualResetEvent e = new ManualResetEvent(false);
        lock (lockObject)
        {
            bool wait = true;

            func().ContinueWith((taskResult) =>
            {
                wait = false;
                e.Set();
            });

            if (wait)
            {
                e.WaitOne();
            }
        }
    });
}