Runtime: Make ConfigureAwait(false) the default behaviour for Tasks

Created on 12 Jul 2018  路  9Comments  路  Source: dotnet/runtime

The default behaviour when await-ing a Task is to return to the caller thread. This behaviour was designed in the time of WPF and Silverlight, when building responsive UI was in the spotlight, so the API designers wanted to make client app developer's lives very easy.

But on the server side or in any library code we should be using ConfigureAwait(false), meaning the asynchronous continuation can run wherever it wants, it doesn't have to be marshalled back to a specific thread. And .NET Core - so far - is all about server side apps (ASP.NET, Orleans, etc.) and libraries (.NET Standard).

My proposal is to embrace the fact that .NET Core can potentially introduce breaking changes in new versions and change the default behaviour of await-ing Tasks, and make ConfigureAwait(false) the default behaviour. In the .NET Core world it actually wouldn't break anything and in libraries we should also use it anyway. So it would be just a nice little touch that wouldn't hurt anyone, but benefit a lot.

The second part of my proposal is a potential introduction of an attribute (or even C# keyword) that can be applied to a method or a whole class, so any await-ed call would be configured with ConfigureAwait(true) inside. It would be useful later when WPF and WinForms apps will be able to run on top of .NET Core 3.0, and these attributes could be applied typically to code-behind and viewmodel classes/methods. This would be still a major simplification compared to having to use the ConfigureAwait(true) on every single asynchronous call.

area-System.Threading.Tasks enhancement

Most helpful comment

It could be interesting to apply an attribute to a class, something that denotes that configure await false default should be used, instead of true. This attribute could be applied to API classes, utility function classes, etc. The class could still force a ConfigureAwait(true) if needed, but this would be unlikely.

This would save adding the configure await false to all the await calls inside the class.

All 9 comments

In the .NET Core world it actually wouldn't break anything

It would. For example, xunit has its own SynchronizationContext. And anyone can author their own SynchronizationContext/TaskScheduler; if they were using it and expecting by default continuations to be queued back to those, such a change would break them.

and in libraries we should also use it anyway

In most libraries, that's true. But there are explicitly places where it's not.

The second part of my proposal is a potential introduction of an attribute (or even C# keyword) that can be applied to a method or a whole class, so any await-ed call would be configured with ConfigureAwait(true) inside.

This would need to be a request on the language side, e.g.
https://github.com/dotnet/csharplang/issues/645
https://github.com/dotnet/roslyn/issues/7673

I want to add is changing the ConfigureAwait default behavior will be a challenging for anyone writing a netstandard library which will run on net core and full desktop.

@stephentoub is there any action needed from our side here? or can we close this issue?

is there any action needed from our side here? or can we close this issue?

I appreciate the desire for a change here, but I don't think there's any action on this possible right now. I don't think we can or should change the default.

@petroemil feel free to reply back if you have any more questions or anything need to follow up. Thanks for reporting the issue.

You are right, my suggestion might have been going a bit too far, we probably shouldn't just change the default behaviour as it could break things... but it could be made configurable. An attribute that can be applied on method/class/assembly level maybe.

@petroemil You might be interested in https://github.com/dotnet/roslyn/issues/7673.

Edit: never mind, @stephentoub already linked this above.

So, what is default? Documentation does not say

So, what is default? Documentation does not say

When you write await task;, that is equivalent to writing await task.ConfigureAwait(true);.

It could be interesting to apply an attribute to a class, something that denotes that configure await false default should be used, instead of true. This attribute could be applied to API classes, utility function classes, etc. The class could still force a ConfigureAwait(true) if needed, but this would be unlikely.

This would save adding the configure await false to all the await calls inside the class.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

v0l picture v0l  路  3Comments

Timovzl picture Timovzl  路  3Comments

GitAntoinee picture GitAntoinee  路  3Comments

noahfalk picture noahfalk  路  3Comments

yahorsi picture yahorsi  路  3Comments