How to combine async with blocking?

As the famous blog post from Stephen Cleary says , you should never try to run asynchronous code synchronously (for example, through Task.RunSynchronously()

or by accessing Task.Result

). On the other hand, you cannot use async / await inside a statement lock

.

My use case is an ASP.NET Core app that uses IMemoryCache to cache some data. Now that no data is available (for example, the cache has been deleted) I have to fill it up and this has to be protected lock

.

public TItem Get<TItem>(object key, Func<TItem> factory)
{
    if (!_memoryCache.TryGetValue(key, out TItem value))
    {
        lock (_locker)
        {
            if (!_memoryCache.TryGetValue(key, out value))
            {
                value = factory();
                Set(key, value);
            }
        }
    }
    return value;
}

      

In this example, the factory function cannot be asynchronous! What if it needs to be asynchronous?

PS: The highest rated (70+ votes) comment below this answer requires exactly the same but has no answers at all.

EDIT: I think this is not a duplicate question, in the sense that the linked answer is a third party library by the author. Isn't there a solution without third party code? Maybe the mentioned SemaphoreSlim.WaitAsync

one can be used successfully? .. What are the pros and cons of each of them? Can we have a discussion? Please reopen the question. I don't think the question is solved with the linked answer (which just suggests a very subjective, subjective "hack").

+4


source to share





All Articles