为什么返回Task而不是int?(异步和;等待)

本文关键字:int 异步 等待 Task 返回 为什么 | 更新日期: 2023-09-27 18:05:54

假设我运行RunSynchron()。在本例中,它运行Delay(),暂停10秒,同时继续执行程序。Delay()完成后,它返回if语句的值1。但是为什么我必须返回Task<int>而不是int呢?

class Synchron
{
    public async void RunSynchron()
    {
        var delay = this.Delay();
        Console.WriteLine("Now we wait...");
        Console.WriteLine("But we can continue with our work");
        if(await delay == 1)
            Console.WriteLine("Now it's done");
    }
    public async Task<int> Delay()
    {
        await Task.Delay(10000);
        return 1;
    }
}

为什么返回Task<int>而不是int?(异步和;等待)

因为async关键字只是一个围绕返回任务的方法的语法糖。这是它的定义。

在底层,当编译器在同一个方法调用上遇到await时,它将添加完整的异步调用并等待任务的完成。因此,编译器需要一个Task<int>来为您构建代码,最终编译的代码。

请注意,await后面的代码被编码为该方法返回的任务的任务延续。如果你试着自己写的话,会有很多样板文件。这就是async/await关键字如此有用的原因。

这是async/await特性设计的一个不幸的方面,async似乎是方法声明的一部分。

我说"不幸"是因为它是关于方法的实现细节——具体地说,它改变了可能出现在这样一个方法中的代码的性质,从而允许await s出现并将被适当地处理。

它不改变方法的签名(实际上,接口声明中不允许这样做)。因此,如果您有一个返回"某物"的方法,并且在稍后的时间点"某物"可以转换为int,那么您不是在描述一个返回int的方法。在您的示例中,您将"某些东西"存储在delay变量中。那时候还不是int——只是以后可以变成int的东西。

他们可以选择让async"更神奇",让它隐式地改变方法签名,将结果包装在Task中——但这会使实际的返回类型对随机检查不那么明显。如果想要将方法从async转换为非async或反之亦然(您还必须编辑返回类型),则还需要更多的实际编辑