Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Usage of ConfigureAwait in .NET

I've read about ConfigureAwait in various places (including SO questions), and here are my conclusions:

  • ConfigureAwait(true): Runs the rest of the code on the same thread the code before the await was run on.
  • ConfigureAwait(false): Runs the rest of the code on the same thread the awaited code was run on.
  • If the await is followed by a code that accesses the UI, the task should be appended with .ConfigureAwait(true). Otherwise, an InvalidOperationException will occur due to another thread accessing UI elements.

My questions are:

  1. Are my conclusions correct?
  2. When does ConfigureAwait(false) improves performance, and when it doesn't?
  3. If writing for a GUI application, but the next lines doesn't access the UI elements. Should I use ConfigureAwait(false) or ConfigureAwait(true) ?
like image 614
Youssef13 Avatar asked Jul 01 '20 16:07

Youssef13


People also ask

Why do we use ConfigureAwait in C#?

Configure await This is what the ConfigureAwait method enables to do. Calling ConfigureAwait(false) after the task means that we do not care if the code after the await, runs on the captured context or not. In the output console, “True” will be printed since the synchronization context is not kept.

Is ConfigureAwait needed in .NET Core?

NET Core you won't need to spread ConfigureAwait(false) all over your code. Almost! This is almost true, it is still recommended the utilization of ConfigureAwait(false) for libraries as a fallback if those libraries are used within a legacy framework. But for most of the cases yes, in .

When should I use ConfigureAwait true?

In this video we answer the ever popular question “Which do I use, ConfigureAwait True or False?”. The direct answer to this question is: – If you are a writing code for the UI, use ConfigureAwait(true).

Should I use ConfigureAwait false in asp net core?

NET Core or later. Later in the comments to that blog post, David Fowler mentions that "most of ASP.NET Core doesn't use ConfigureAwait(false) and that was an explicit decision because it was deemed unnecessary." Use your own best judgment on whether you need it or not for a specific project.


1 Answers

To answer your questions more directly:

ConfigureAwait(true): Runs the rest of the code on the same thread the code before the await was run on.

Not necessarily the same thread, but the same synchronization context. The synchronization context can decide how to run the code. In a UI application, it will be the same thread. In ASP.NET, it may not be the same thread, but you will have the HttpContext available, just like you did before.

ConfigureAwait(false): Runs the rest of the code on the same thread the awaited code was run on.

This is not correct. ConfigureAwait(false) tells it that it does not need the context, so the code can be run anywhere. It could be any thread that runs it.

If the await is followed by a code that accesses the UI, the task should be appended with .ConfigureAwait(true). Otherwise, an InvalidOperationException will occur due to another thread accessing UI elements.

It is not correct that it "should be appended with .ConfigureAwait(true)". ConfigureAwait(true) is the default. So if that's what you want, you don't need to specify it.

  1. When does ConfigureAwait(false) improves performance, and when it doesn't?

Returning to the synchronization context might take time, because it may have to wait for something else to finish running. In reality, this rarely happens, or that waiting time is so minuscule that you'd never notice it.

  1. If writing for a GUI application, but the next lines doesn't access the UI elements. Should I use ConfigureAwait(false) or ConfigureAwait(true) ?

You could use ConfigureAwait(false), but I suggest you don't, for a few reasons:

  1. I doubt you would notice any performance improvement.
  2. It can introduce parallelism that you may not expect. If you use ConfigureAwait(false), the continuation can run on any thread, so you could have problems if you're accessing non-thread-safe objects. It is not common to have these problems, but it can happen.
  3. You (or someone else maintaining this code) may add code that interacts with the UI later and exceptions will be thrown. Hopefully the ConfigureAwait(false) is easy to spot (it could be in a different method than where the exception is thrown) and you/they know what it does.

I find it's easier to not use ConfigureAwait(false) at all (except in libraries). In the words of Stephen Toub (a Microsoft employee) in the ConfigureAwait FAQ:

When writing applications, you generally want the default behavior (which is why it is the default behavior).

Edit: I've written an article of my own on this topic: .NET: Don’t use ConfigureAwait(false)

like image 54
Gabriel Luci Avatar answered Sep 23 '22 10:09

Gabriel Luci