Follow-up to this question. I have a library with many async methods that thinly wrap HttpClient
. Effectively they just do some setup and directly return the Task
returned from the HttpClient
call:
public Task DoThingAsyc() {
// do some setup
return httpClient.DoThingAsync();
}
I'm pondering whether to add ConfigureAwait(false)
to these calls. The prevailing wisdom seems to be "yes, always do that in libraries." But in this case, it would introduce some (perhaps negligible) overhead, because ConfigureAwait
returns a ConfiguredTaskAwaitable
which would need to be wrapped back into a Task
in order to not change the method signature. Certainly not hard to code:
public async Task DoThingAsyc() {
// do some setup
return await httpClient.DoThingAsync().ConfigureAwait(false);
}
My question is, will the efficiency benefits of ConfigureAwait(false)
likely outweigh the extra overhead introduced in this case? What example above would be considered the better practice?
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.
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!
In the code that relies on the asynchronous programming model ( async / await keywords), ConfigureAwait() calls are often used to manage the synchronization context.
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).
No, don't do this.
Since you're not using await
, you're not supposed to configure for it in advance. It's the responsibility of the caller of your library to do the ConfigureAwait
call. And the caller may well want to call ConfigureAwait(true)
instead of ConfigureAwait(false)
- you don't know that.
Calling ConfigureAwait(false)
in library code is best practice only when you await on it in the library.
In most cases, code like this:
async Task<Something> DoSomethingAsync()
{
return await DoSomethingElseAsync().ConfigureAwait(false);
}
Is equivalent to:
Task<Something> DoSomethingAsync()
{
return DoSomethingElseAsync();
}
if DoSomethingElseAsync
respects the Task
contract (for instance, if it returns a failed Task
instead of throwing exceptions).
Creating an additional state machine for that is just adding one layer of wrapping code with no added value - it is better to simply return the Task
directly.
In other words: you get no efficiency benefit whatsoever from doing this, quite the contrary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With