嵌套的async/await方法

21

我正在编写一个包装第三方Web服务调用的库,并尝试使该库使用新的async/await功能。以下示例中async/await关键字的正确用法是什么?

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);        
    }
}

为了让我的调用者能够等待DoSomethingAsync方法,我是否需要在该方法中添加async和await关键字?还是直接返回Task就可以了?在这种嵌套情况下,有更好的模式吗?

我认为使用DoSomethingAsync方法是正确的选择,这样做是否正确?我认为在构建库时,使用DoSomethingElseAsync似乎是错误的方法。

2个回答

17

任何Task都可以被等待,不管它来自哪里。

我不确定为什么DoSomethingAsync只是调用DoSomethingCore,因为DoSomethingAsync同样可以是async并使用await

还有一个通用规则,在库方法中应使用ConfigureAwait(false)

编辑:如果不需要使用await,那么不要将方法设置为async。使用async会增加一些开销(请查看Channel9上的Stephen Toub的Zen of Async Performance视频)。如果可以只返回一个Task(例如DoSomethingAsync),那么就这样做。


DoSomethingAsync调用DoSomethingCore,因为在我的实际场景中,我有两个类似的公共方法,它们通过使用一个核心方法来共享功能。我会研究一下ConfigureAwait方法,因为我之前没有见过这个。 - Brian Vallelunga
我添加了一个DoSomethingElseAsync()方法来更好地解释我所困惑的内容。我相信你已经充分解释了这个问题,并且DoSomethingAsync()方法是库方法的正确选择。 - Brian Vallelunga
@StephenCleary -- 那么,方法签名应该是 public Task<ApiResult> DoSomethingElse() 并且只需返回 this.DoSomethingCore(); ?基本上,既然它没有使用 await,所以不需要使用 async 关键字,因此他不应该将方法命名为 DoSomethingElseAsync()。这正确吗?这很明显是为了澄清命名约定,我知道这不是语法问题。 - Andy
2
@Sonic:Async 后缀是一种约定,它表明它被设计为由 await 使用,而不是用 await 实现。因此,即使 DoSomethingElseAsync 不使用 async/await,它仍应该使用 Async 后缀。 - Stephen Cleary

4
下面的公式是可行的,但很可能会导致额外的开销(因为需要一个额外的回调来处理附加的async/await方法)。
public async Task<ApiResult> DoSomethingElseAsync()
{
    return await this.DoSomethingCore();
}

直接返回任务(Task)更简单,因为您可以在其他地方等待该任务(Task),而无需将方法实现为“async”。异步/等待(Async/await)很像使用“yield return”;它执行一些编译器魔法来实现“yielding”,但枚举本身并不关心您如何实现它。同样,一个“await”调用不关心可等待对象如何工作,只要它是可等待的即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接