I'm writing a library that wraps a third party web service call and am trying to make the library use the new async/await features. What is the proper use of the async/await keywords in the following example?
public class MyApi
{
public Task<ApiResult> DoSomethingAsync()
{
return this.DoSomethingCore();
}
public async Task<ApiResult> DoSomethingElseAsync()
{
return await this.DoSomethingCore();
}
private async Task<ApiResult> DoSomethingCore()
{
var httpClient = new HttpClient();
var httpResponseMessage = await httpClient.GetAsync("some url");
var rawResultText = await httpResponseMessage.Content.ReadAsStringAsync();
return new ApiResult(rawResultText);
}
}
To allow my caller to await the DoSomethingAsync method, should that method also have the async and await keywords added to it? Or is it fine as-is because it returns a Task? Is there a better pattern for this sort of nesting?
I think the DoSomethingAsync method is the correct way to go here, is that correct? I believe DoSomethingElseAsync seems the wrong approach when building a library.
async functions returning promises is a good thing because you can nest async functions.
In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.
The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.
Any Task
can be awaited, regardless of where it came from.
I'm not sure why DoSomethingAsync
just calls DoSomethingCore
, since DoSomethingAsync
could just as easily be async
and use await
.
There is also a general rule that you should use ConfigureAwait(false)
in library methods.
Edit: If you don't need to use await
, then don't make the method async
. async
will add some overhead (check Channel9 for Stephen Toub's Zen of Async Performance video). If you can just return a Task
(like DoSomethingAsync
), then do it that way.
The formulation below is functional, but will likely cause additional overhead (due to having a secondary callback for the additional async/await method.)
public async Task<ApiResult> DoSomethingElseAsync()
{
return await this.DoSomethingCore();
}
It's simpler to return the Task directly, as you can always await that Task elsewhere without having to have the method implemented as 'async'. Async/await is a lot like using 'yield return'; it does some compiler magic to implement the 'yielding', but the enumeration itself doesn't care how you implement it. Likewise, an 'await' call doesn't care how the awaitable works, as long as it's awaitable.
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