ASP.NET requires using the same SynchronizationContext for
asynchronous operations in the controller, otherwise it blocks the
running thread.
I'm not really sure what that statement means. ASP.NET doesn't require "the same" synchronization context. In order for you to be inside your HttpContext
, you need that SynchronizationContext
.
But what purpose led Microsoft to use the same SynchronizationContext
?
I suggest you read It's All About SynchronizationContext to get the bigger picture about sync contexts. Basically, it's a mechanism which allows you to post continuations on a particular thread. It can be used, for example, to marshal work back onto the UI message loop thread inside UI applications.
May be using of the ConfigureAwait(false), which disables the same
sync context restriction, might lead to e.g. unpredictable behavior or
performance issues
On the contrary. Marshaling work back onto the sync context does have (very minimal) overhead, as the request needs to be posted (using the abstract SynchronizationContext.Post
) back onto the desired thread and context. By using ConfigureAwait(false)
, you're saving that time and simply continuing execution on which ever thread was allocated.
Thus, is it really good practice to use the ConfigureAwait(false)
wherever is possible?
The primary reason to do that is to avoid deadlocks. When someone calling Task.Result
or Task.Wait
instead of asynchronously waiting using await
, you get the classic deadlock scenario where the sync context is attempting to post the continuation back onto the thread, but it is currently blocked because Result
and Wait
are blocking calls. The other reason is the minor performance overhead you get.
Edit:
Why doesn't Microsoft encapsulate this method inside the Task class?
It looks like the ConfigureAwait(false) has just only the pluses. Is
there any minuses?
Let's image the following scenario: You execute a method which returns a Task
and is awaited using await
, and right after that you update some UI element. Now, what would be more natural to you? Would you prefer to implicitly return to the same "environment" you were before (the UI thread), or would you prefer that you had to explicitly specify that you want to return to that same environment?
I think that the former "feels" more natural to the user.
Example:
public Task FetchAndReturnAsync(string url)
{
var httpClient = new HttpClient();
return httpClient.GetAsync(url);
}
You call it like this:
var awesomeUiResult = await FetchAndReturnAsync("http://www.google.com");
textBox.Text = awesomeUiResult;
What do you think should happen? Is it more natural for you to be able to update the text box after the await, or for it to fail because you're now not inside your original context?