想知道为什么我们应该指定async
方法确实返回Task对象。
使用async
关键字指定它似乎是多余的,因为您没有真正创建Task
对象,所以它很混乱。
据我所知,编译器会为Task对象创建发出必要的代码(无论是在等待调用还是用新任务包装返回。)。
我真的不喜欢声明类型和返回类型之间的不一致。
答案 0 :(得分:8)
这不是一个真正的问题:它更像是一个咆哮,因此不是特别适合StackOverflow:
我真的不喜欢声明类型和返回类型之间的不一致。
如果你想抱怨,可以开始写博客并抱怨。让我们将其重新表述为问题:
async
方法返回的声明类型可能是Task<int>
,但该方法中return
语句返回的表达式必须可以隐式转换为int
,不是Task<int>
。这可能令人困惑。什么设计原则证明了这种行为的合理性?
你是对的,这可能令人困惑。令人困惑的是,因为async
方法将我们非常习惯的两件事分开作为一件事。这两件事是:
在同步方法中,这两件事总是一样的,因为调用者中的恢复点是同步方法的延续。但是异步方法的重点在于调用者中的代码不是方法的延续。通过设置与其关联的任务的继续来控制方法的继续。
这就是声明的返回类型和return
语句的类型不同的原因。调用者需要Task<int>
,但该方法的延续需要int
。 return
语句表示“此方法已完成;无论方法是同步还是异步,都将此值赋予我的继续”。
答案 1 :(得分:5)
听起来你问为什么public async int MyMethodAsync()
不会自动编译为实际返回Task<int>
的方法。
答案是最小惊喜的原则:方法签名中声明的返回类型始终是实际的返回类型 这样,当您读取方法声明时,您始终可以知道调用方法时看到的实际返回类型,而无需查看修饰符并记住特殊规则。
答案 2 :(得分:2)
我a blog post详细描述了推理。推断返回类型was considered但他们决定不这样做。
使用显式返回类型,async
关键字更多是实现细节。拥有显式返回类型有两个原因:
async void
和async Task
之间存在差异。使用推断的返回类型,没有明确的方法来定义async void
方法。