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?
No,
ConfigureAwait
as its name suggests, configures theawait
. If you don't need toawait
then you don't need to configure it.There's no added value in adding async-await just to use
ConfigureAwait
as it only affects your method and not the calling method. If the caller needs to useConfigureAwait
they will do so themselves.Having an async method instead of a simple
Task
-returning method is a valid choice for many reasons (e.g. exception handling), and it will require usingConfigureAwait
butConfigureAwait
is not a good reason for doing that by itself.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 theConfigureAwait
call. And the caller may well want to callConfigureAwait(true)
instead ofConfigureAwait(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:
Is equivalent to:
if
DoSomethingElseAsync
respects theTask
contract (for instance, if it returns a failedTask
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.