davidfowl / AspNetCoreDiagnosticScenarios

This repository has examples of broken patterns in ASP.NET Core applications
7.69k stars 740 forks source link

ConfigureAwait(false) when yes / no #31

Open imperugo opened 5 years ago

imperugo commented 5 years ago

Great repo David.

Any best practice about ConfigureAwai(false)? When is good to use it and when is not?ù

Thanks

MaximRouiller commented 5 years ago

Looks like it's scenario yet to be written

https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/366c96205ae62e9c2d8cb3f46dd6ac14b5cdda29/AsyncGuidance.md#configureawait

WiredUK commented 5 years ago

There's already some good info on this here.

saltukkos commented 5 years ago

Also this section need "NOTE" about "result is actually semantically different to async/await", that in case of ConfigureAwait(false) they are actualy equal.

jecaestevez commented 5 years ago

will be great to have define this very soon xD I read about don't do ConfigureAwait(false) https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html and in other place I see it's very recommended but if finally it's necessary configure then the code in many place

kapsiR commented 5 years ago

@jecaestevez I really recommend to read the cookbook from VS, as mentioned from WiredUK. There is also a short answer available. (@davidfowl Maybe we can copy/paste this section into the AsyncGuidance? 😉)

The blog post you mentioned, in my opinion, refers to "don't block async code" and don't really explain a general solution for ConfigureAwait(). (Avoid using Task.Result and Task.Wait)

slang25 commented 5 years ago

Agreed with @kapsiR and @WiredUK, that is absolutely the best answer to this question and should be repeated in this guidance, as it has the TL;DR plus the full nuanced answer for those that want to fully understand it.

mikeblakeuk commented 3 years ago

Any news on this?

steveoh commented 3 years ago

I noticed omnisharp started recommending configure await for every async method now. Seems a little incorrect based on this discussion. Has anyone else noticed this?

negativeeddy commented 3 years ago

I really dislike the "put configureawait everywhere" drumbeat. If I have to do something everywhere I try to find a better solution.

The need to put configureawait(false) everywhere stems from libraries wanting to not block the synchronization context of an arbitrary caller. The configureawait pattern only guarantees this it if you do it at every async call because you don't know if any of the previous calls will actually complete asynchronously. But you can also get the same result by just stripping the context at your public entry point and guaranteeing it is restored before finishing by using something like this https://github.com/negativeeddy/blog-examples/blob/master/ConfigureAwaitBehavior/ExtremeConfigAwaitLibrary/SynchronizationContextRemover.cs

kapsiR commented 3 years ago

There is a very good article from @stephentoub available.

He also mentions some proposals how this whole thing could be addressed:

There is also a proposal for more options with ConfigureAwait:

I think until there is any decision here, we can stick with the recommendations of Stephen:

Even with these special cases, the general guidance stands and is a very good starting point: use ConfigureAwait(false) if you’re writing general-purpose library / app-model-agnostic code, and otherwise don’t.