async/await 的调用链......等待可等待的还是返回可等待的?

Posted

技术标签:

【中文标题】async/await 的调用链......等待可等待的还是返回可等待的?【英文标题】:Call chain for async/await ... await the awaitable or return the awaitable? 【发布时间】:2017-12-03 23:05:31 【问题描述】:

给定一个异步方法:

public async Task<int> InnerAsync()

    await Task.Delay(1000);
    return 123;

通过中间方法调用,中间方法是等待异步方法IntermediateA还是仅仅返回TaskIntermediateB

public async Task<int> IntermediateA()

    return await InnerAsync();


private Task<int> IntermediateB()

    return InnerAsync();

据我所知,调试器似乎两者的工作方式完全相同,但在我看来,IntermediateB 应该通过避免在状态机中再输入一个 await 来获得更好的性能。

是吗?

【问题讨论】:

区别在于异常处理。为了更好地理解这一点,我建议你尝试从内部函数中抛出一个异常,看看事情是如何工作的。 谢谢。我根本没有考虑异常处理。 “在我看来 IntermediateB 应该表现更好” - 是的,但差异将是几纳秒。它还可以在生成的二进制文件中节省几十个字节。 我建议你阅读Eliding Async and Await 【参考方案1】:

这两种方法存在细微差别。如果你 await 失败的任务,异常将在该方法中抛出,但如果你通过任务认为该方法然后 await 它,异常将在消费者方法中抛出。另一个差异更为罕见,如果消费者等待任务并且如果它发生延迟,则可以在等待点完成任务并绕过状态机。

【讨论】:

谢谢。我根本没有考虑异常处理。 性能怎么样?这不是创建两个状态机(等待内部)吗? 如果没有 try/catch,异常将传播给调用者。你能指出一个实质性的实际差异吗?

以上是关于async/await 的调用链......等待可等待的还是返回可等待的?的主要内容,如果未能解决你的问题,请参考以下文章

async await 实现Sleep 等待效果

Async Await使用场景

Async Await使用场景

Async Await使用场景

Async Await使用场景

async await 实现Sleep 等待效果