Always use the 'async' and 'await' keywords in asynchronous methods in a library?

ぃ、小莉子 提交于 2019-11-30 08:35:36
David Pine

Should I use async await in library?

It all depends. If you're going to take advantage of the asynchronous programming paradigm, then the answer is "yes," the async and await keywords are needed most of the time. More than likely, you will find yourself needing to use async/await. That is because in most situations it would be difficult to use only Task and Task<T> as you will more than likely need to reason about the results of the async operations that you invoke.

Additionally, based on your question it seems as though you may have some confusion about the keywords themselves and how they relate to the Task and Task<T> types. Allow me to clarify this for you.

The async keyword allows a method to use the await keyword. The best practice is to have all async methods return either Task or Task<T> unless you are unable to (for example, a button click event handler as you demonstrated above).

Methods that return Task or Task<T> represent asynchronous operations. When you are in a library it is suggested to always use .ConfigureAwait(false) for reasons detailed here. Additionally, I always point people to this detailed article on the subject.

To differentiate the two approaches in your question:

The method below returns a Task<SignResponse>. This is an async operation that represents the work to sign in. The method can be awaited by the caller to get SignResponse.

private Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
    return _service.SignAsync(request);
}

Likewise, this version does the same thing...except that the async/await keywords are not needed. The reason they are not needed is that the method itself does not need to use SignResponse and therefore it could simply return Task<SignResponse> as shown above. And as you indicated in your question, there is indeed a penalty when you use the async/await keywords when they are not needed. Doing so adds an extra state machine step as the result is yielded, since its awaited.

private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
    return await _service.SignAsync(request).ConfigureAwait(false);
}

Finally, if you needed to reason about the response, you could use the aforementioned keywords to do so like this:

private async Task<SignResponse> GetSignDataAsync(SigningRequestType request)
{
    var result = await _service.SignAsync(request).ConfigureAwait(false);
    if (result.SomeProperty == SomethingWeCareToCheck)
    {
        _log.Log("Wow, this was un-expected...");
    }
    return result;
}

Don't take my word for it, because I never understood async/await that well, but what bothered me most about the idea was that all methods using async had to be marked as async as well, which annoyed me to no end.

I guess in a library giving people the option to choose how to use the methods is a good thing, so you should use async, however I always found it more clear to explicitly use the Tasks directly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!