The C# compiler already warns us if we have a method that has the async
modifier but does not use the await
operator.
According to this answer there's no point adding an await
to the end of an async method (and in that case, just remove the async
modifier).
But what if the method has an expensive synchronous operation it needs to perform before calling a subsequent true async method?
For example, if I'm using HttpClient
:
private readonly HttpClient client = ...
public Task<HttpResponseMessage> CallMyWebServiceMethod() {
HttpRequestMessage request = this.SomeExpensiveButSynchronousMethod();
return this.client.SendAsync( request );
}
This code would block the caller (due to SomeExpensiveButSynchronousMethod
).
However, if I change the code to this:
public async Task<HttpResponseMessage> CallMyWebServiceMethod() {
HttpRequestMessage request = this.SomeExpensiveButSynchronousMethod();
return await this.client.SendAsync( request );
}
and I call it like so:
HttpResponse response = await myWrapper.CallMyWebServiceMethod();
...I understand the TPL would spin up a background thread immediately and then run CallMyWebServiceMethod
in the background thread, resuming whatever the parent code wants, making the entire call non-blocking in the process, before resuming after the Task completes and returns the HttpResponse
.
...if that's the case then it seems contradictory.
If I'm wrong, and the call is blocking until it gets to SendAsync
then how can I execute SomeExpensiveButSynchronousMethod
on the same background thread as the HttpClient
uses for its request?