.NET 4.5 async await and overloaded methods

2019-04-03 09:54发布

问题:

I have an async method:

public async Task<UserLoginExResult> LoginExAsync(CustomTable exRequest, string language, bool throwEx = true)
{
    UserLoginExResult result = await UserService.LoginExAsync(UserGroup, language, TimezoneOffset, GetDeviceInfo(), GetLoginProperties(), exRequest);

    ProcessLoginResult(result, false, throwEx);

    return result;
}

And an overload:

public Task<UserLoginExResult> LoginExAsync(CustomTable exRequest, bool throwEx = true)
{
    return LoginExAsync(exRequest, Language.ID, throwEx);
}

I'm not sure if I should mark the overloaded one (the one with fewer parameters) as async and use await? I guess I should not but can you tell me what whould happen if I would do that? I'm quite lost in here and not really sure what Task it would wait for? Would it create an extra Task or await doesn't create a new Task?

回答1:

No, there's little benefit in using an async method when it's just going to wrap and unwrap an existing one. It's fine to just have a "normal" method here, delegating to the "real" async method.

(They're not quite the same - for example, if the UserService.LoginExAsync method throws an exception rather than returning a failed task, the async/await version will just return a failed task, whereas the other version will also throw immediately.)



回答2:

The async keyword only enables the await keyword. In your case, you can return the Task directly, so there's no need for the async keyword. async would only add overhead without adding any value.

For more information, see Stephen Toub's Zen of Async talk. He addresses this situation directly.



回答3:

It would really only be worth doing if you were doing additional work in your overload, e.g.

public async Task<UserLoginExResult> LoginExAsync(CustomTable exRequest, bool throwEx = true)
{
    Task<UserLoginExResult> result = await LoginExAsync(exRequest, Language.ID, throwEx);

    //Do some work here that depends on the result from the task completeion

    return result;
}

But as you are not, it isn't!



回答4:

The overload doesn't need to be marked as async as it doesn't internally await anything, so therefore there's nothing for the compiler to rewrite.