Why ConfigureAwait(false) does not work while Task.Run() works?

I believe Lukazoid is correct. To put it another way...

// This Create Method results in Deadlock
public async Task<string> Create(MyConfig config)
{
  Document doc = await Client.CreateDocumentAsync(CollectionUri, config).ConfigureAwait(false);
  return doc.Id;
}

You can't just stick a ConfigureAwait(false) at one level and have it magically prevent deadlocks. ConfigureAwait(false) can only prevent deadlocks if it is used by every await in the transitive closure of that method and all methods it calls.

In other words, ConfigureAwait(false) needs to be used for every await in Create (which it is), and it also needs to be used for every await in CreateDocumentAsync (which we don't know), and it also needs to be used for every await in every method that CreateDocumentAsync calls, etc.

This is one reason why it is such a brittle "solution" to the deadlock problem.


In the first example, the implementation of Client.CreateDocumentAsync is deadlocking because it is trying to execute a continuation using the current SynchronizationContext.

When using 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.