为什么异步方法返回类型不能从Task派生?

时间:2016-07-06 05:32:26

标签: c# asynchronous async-await

我有一个班级(简化样本,只显示相关部分)

public class AsyncScenario : Task<Scenario>
{
    public async AsyncScenario Test(Func<Task> action)
    {
        return await this;           
    }
}

我无法编译这个因为方法的返回类型:

  

编译器错误CS1983:“异步方法的返回类型必须为void,任务或任务&lt; T&gt;”

为什么异步方法不允许返回从Task<T>派生的类?

2 个答案:

答案 0 :(得分:7)

因为C#规范是这样说的吗?如果没有Eric Lippert或其他一些语言设计团队的人员在,你就不会得到更好的答案。其他任何事情都是纯粹的猜测和意见。

那就是说,假设在async方法中,return语句隐含了返回值,您认为规范规则在这样的示例中应该是什么?显然await this解析为Scenario对象... C#编译器应该如何从该表达式类型合成新的AsyncScenario对象?

我想你可能会提出一些额外的规则,你可以在规范中加入一些明确规定某种机制的规则。但在我看来,这些规则显着比规范现在存在的规则更复杂,其中返回类型始终是规范作者已知的类型,并且具有明确的规则在方法第一次返回时创建,同样重要的是,更改执行return语句的状态。

我觉得这些规则可能存在,只是因为这样做会需要过多的努力,并且会大大增加编译器的复杂性以及所述编译器中出现错误的可能性。


†说到这一点,有点搜索挖出金色:Why must async methods return Task?,由VB.NET语言设计师Lucian Wischik编写(但该文章同样适用于C#)。另见Jon Skeet在Using a generic type as a return type of an async method的回答。

答案 1 :(得分:1)

您可以等待任何使用GetAwaiter方法返回类型的方法:

PlasticBottle