Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When I cannot use ConfigureAwait(false)?

According to best practices it is recommended to use .ConfigureAwait(false) with async/await keywords if you can:

await Task.Run(RunSomethingAsync).ConfigureAwait(false);

Can you please give me an example of a situation when I cannot use .ConfigureAwait(false)?

like image 969
Andrei Avatar asked Sep 03 '15 13:09

Andrei


People also ask

Which do I use ConfigureAwait True or false?

In 99% of the cases, you should use ConfigureAwait(false). In . NET Framework by default the Task execution will continue on the captured context, this is ConfigureAwait(true).

Should I always use ConfigureAwait false?

As a general rule, every piece of code that is not in a view model and/or that does not need to go back on the main thread should use ConfigureAwait false. This is simple, easy and can improve the performance of an application by freeing the UI thread for a little longer.

What is ConfigureAwait () used for?

ConfigureAwait in ActionIt is what happens when you await a task. You capture the current context before awaiting the task, leaving it to the task context, then recovering (re-entering) it back when the task completes. This process is highly expensive and in many scenarios, you do not need it!

Is ConfigureAwait true by default?

To improve performance and avoid potential deadlocks, use ConfigureAwait(false) in any non-UI code. The exception here is app-level code, such as Windows Forms, WPF, and ASP.NET. ConfigureAwait(true) corresponds to the default behavior and does nothing meaningful, therefore such calls can be safely omitted.


2 Answers

You "cannot" use ConfigureAwait(false) when you actually care about the synchronization context you're in. For example, imagine the following in a GUI application:

public async void SomeButtonClick(object sender, EventArgs e)
{
    var result = await SomeAsyncOperation().ConfigureAwait(false);
    textBox.Text = result;
}

When you return from ConfigureAwait, you wont be back on the UI thread. This will cause an InvalidOperationException.

like image 123
Yuval Itzchakov Avatar answered Oct 18 '22 09:10

Yuval Itzchakov


From the source: Asynchronous .NET Client Libraries for Your HTTP API and Awareness of async/await's Bad Effects:

When you are awaiting on a method with await keyword, compiler generates bunch of code in behalf of you. One of the purposes of this action is to handle synchronization with the UI (or main) thread. The key component of this feature is the SynchronizationContext.Current which gets the synchronization context for the current thread. SynchronizationContext.Current is populated depending on the environment you are in. The GetAwaiter method of Task looks up for SynchronizationContext.Current. If current synchronization context is not null, the continuation that gets passed to that awaiter will get posted back to that synchronization context.

When consuming a method, which uses the new asynchronous language features, in a blocking fashion, you will end up with a deadlock if you have an available SynchronizationContext. When you are consuming such methods in a blocking fashion (waiting on the Task with Wait method or taking the result directly from the Result property of the Task), you will block the main thread at the same time. When eventually the Task completes inside that method in the threadpool, it is going to invoke the continuation to post back to the main thread because SynchronizationContext.Current is available and captured. But there is a problem here: the UI thread is blocked and you have a deadlock!

like image 43
Rahul Tripathi Avatar answered Oct 18 '22 10:10

Rahul Tripathi