1

想知道为什么我们应该指定该async方法确实返回 Task 对象。

用关键字指定它似乎是多余的,async而且由于您并没有真正创建Task对象,因此会造成混淆。

据我了解,编译器确实为创建任务对象发出了必要的代码(无论是在等待调用还是用新任务包装返回。)。

我不太喜欢声明类型和返回类型之间的不一致。

4

3 回答 3

8

这不是一个真正的问题:它更像是一个咆哮,因此并不特别适合 StackOverflow:

我不太喜欢声明类型和返回类型之间的不一致。

如果您想投诉,请创建一个博客并对此进行投诉。让我们将其重新表述为一个问题

例如,方法返回的声明类型async可能是,Task<int>但该return方法中的语句返回的表达式必须隐式转换为int,而不是Task<int>。这可能会令人困惑。什么设计原则证明了这种行为?

你是对的,这可能会令人困惑。这是令人困惑的,因为async方法将我们非常习惯将其视为一件事的两件事分开。这两件事是:

  • 在此方法的调用者中恢复控制时返回什么类型的对象?
  • 什么类型的对象从方法传递到它的延续?请记住,方法的延续方法完成时运行的代码

在同步方法中,这两件事总是相同的,因为调用者中的恢复点同步方法的延续。但是异步方法的全部意义在于调用者中的代码不是方法的延续。方法的继续是通过设置与其关联的任务的继续来控制的。

这就是为什么声明的返回类型和赋予return语句的类型不同的原因。调用者需要 aTask<int>但方法的延续需要int. 该return语句的意思是“此方法已完成;将此值赋予我的继续”,无论该方法是同步的还是异步的。

于 2013-05-29T15:02:46.760 回答
5

听起来您在问为什么public async int MyMethodAsync()不自动编译为实际返回的方法Task<int>

答案是最不意外的原则:方法签名中声明的返回类型始终是实际的返回类型。
这样,当您阅读方法声明时,您始终可以知道调用该方法时看到的实际返回类型,而无需查看修饰符并记住特殊规则。

于 2013-05-29T14:16:55.707 回答
3

我有一篇博客文章详细描述了推理。已考虑推断返回类型,但他们决定不这样做。

对于显式返回类型,async关键字更多的是实现细节。具有显式返回类型有两个原因:

  • 方法签名是一致的(在声明点与使用 IntelliSense 或反射观察时相同)。
  • async void和之间有区别async Task。使用推断的返回类型,没有明确的方法来定义async void方法。
于 2013-05-29T14:24:02.197 回答