为什么这个async/await代码生成"...并非所有代码路径都返回一个值"?

Hol*_*osa 10 c# asynchronous task-parallel-library async-await c#-5.0

希望这不是重复,但这里有5000多个问题,"并非所有代码路径都返回值"!

很简单,为什么这个非泛型实现的方法编译得很好:

    public static async Task TimeoutAfter(this Task task, int millisecondsTimeout)
    {
        if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
            await task;
        else
            throw new TimeoutException();
    }
Run Code Online (Sandbox Code Playgroud)

这种使方法通用的尝试产生Return state missing/ ... not all code paths return a value警告/错误?:

    public static async Task<T> TimeoutAfter<T>(this Task<T> task, int millisecondsTimeout)
    {
        if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
            await task;
        else
            throw new TimeoutException();
    }
Run Code Online (Sandbox Code Playgroud)

Chr*_*non 11

非泛型Task类型在某种程度上等同于一种等待的void方法.就像void方法一样,你不能从返回类型为的方法返回任何东西Task,这就是第一个例子编译的原因.但是,第二个示例需要泛型类型的返回值,并且您没有在等待另一个调用的路径中提供一个返回值.

从报价参考MSDN上的async关键词,特别是关于返回类型.

如果方法完成时没有返回有意义的值,则使用Task.也就是说,对该方法的调用返回一个Task,但是当Task完成时,任何等待Task的await表达式都会返回void.

  • 我的理解是await表达式的值是*apply*到返回值,所以它不等于返回Void,但是等待它本身就是`System.Void`. (2认同)

Dav*_*son 7

在第二个例子中,你给了你没有返回任何东西.(参见Chris Hannon的回答为什么).

public static async Task<T> TimeoutAfter<T>(this Task<T> task, int millisecondsTimeout) {
    if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
        return await task; // return the Task of T
    else
        throw new TimeoutException();
}
Run Code Online (Sandbox Code Playgroud)

除了@ChrisHannon所说的,还有等待文档.

...如果await应用于返回a的方法调用的结果Task<TResult>,则await表达式的类型为TResult.如果await应用于返回a的方法调用的结果Task,则await表达式的类型为void....