一尘不染

返回void和返回Task有什么区别?

c#

在查看各种C#异步CTP示例时,我看到一些返回的异步函数void,以及其他一些返回非泛型的函数Task。我可以看到为什么Task<MyType>异步操作完成后,返回a
有助于将数据返回给调用方,但是我看到的具有返回类型的函数Task从不返回任何数据。为什么不回来void


阅读 1022

收藏
2020-05-19

共1个答案

一尘不染

SLaks和Killercam的答案很好。我以为我会添加更多上下文。

您的第一个问题实质上是关于可以标记哪些方法async

标为A的方法async可以返回voidTaskTask<T>。它们之间有什么区别?

一个Task<T>返回异步方法可以等待,并在任务完成时,它会毫无顾忌了一个T.

一个Task返回异步方法可以等待,而当任务完成时,任务的延续计划运行。

void返回异步方法不能等待;
这是一种“忘了忘了”的方法。它确实是异步工作的,您无法知道何时完成。这有点奇怪。正如SLaks所说,通常只有在创建异步事件处理程序时才这样做。事件触发,处理程序执行;没有人会“等待”事件处理程序返回的任务,因为事件处理程序不会返回任务,即使它们返回了,什么代码也可以将任务用于某些任务?首先,通常不是用户代码将控制权转移到处理程序。

在评论中,您的第二个问题实质上是关于可以await编辑的内容:

可以采用哪种方法await?可以采用空洞归位法await吗?

不可以,无法等待返回空隙的方法。编译器将转换await M()为对的调用M().GetAwaiter(),其中GetAwaiter可能是实例方法或扩展方法。等待的价值必须是您可以获得等待者的价值;显然,返回空值的方法不会产生可用于获取等待者的值。

Task-返回方法可以产生等待的值。我们期望第三方将希望创建自己的Task可以等待的对象的实现,而您将能够等待它们。然而,你将不会被允许申报async方法是什么回报,但是voidTask还是Task<T>

(更新:我的最后一句话可能被C#的未来版本所伪造;有人建议允许异步方法的任务类型以外的返回类型。)

(更新:上面提到的功能使它进入了C#7。)

2020-05-19