I'm calling an async library method with ConfigureAwait(false). But, I still end up with deadlock. (I'm using it in ASP.NET controller API)
But, if I use same method wrapped into Task.Run() it works fine.
My understanding is, If library method is not using ConfigureAwait internally then adding ConfigureAwait won't solve the problem as in the library call it will result in deadlock (we block on it by using .Result). But, if that's the case why does it work in Task.Run() as it will fail to continue in same context/thread.
This article talks about it. Btw, I have ready plenty of articles by Stephen Cleary. But, why Task.Run() works is a mystery.
// This Create Method results in Deadlock
public async Task<string> Create(MyConfig config)
Document doc = await Client.CreateDocumentAsync(CollectionUri, config).ConfigureAwait(false);
// Uses Task.Run() which works properly, why??
public string Create(MyConfig config)
Document doc = Task.Run(() => Client.CreateDocumentAsync(CollectionUri, config)).Result;
public ActionResult CreateConfig(MyConfig config)
string id = Create(config).Result;
In the first example, the implementation of
Client.CreateDocumentAsync is deadlocking because it is trying to execute a continuation using the current
Task.Run, the delegate will be invoked on a ThreadPool thread, this means there will be no current
SynchronizationContext so all continuations will be resumed using a ThreadPool thread. This means it will not deadlock.
Out of interest, why is your
CreateConfig method not async? Most recent versions of MVC and WebAPI support asynchronous methods, getting rid of the
.Result would be the best solution.