12

これが繰り返されないことを願っていますが、ここには「すべてのコードパスが値を返すわけではない」という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();
    }

メソッドをジェネリックにしようとすると、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();
    }
4

2 に答える 2

11

非ジェネリックTask型は、待機可能なvoidメソッドとある程度同等です。voidメソッドと同様に、returnタイプが、であるメソッドからは何も返すことができませんTask。これが、最初の例がコンパイルされる理由です。ただし、2番目の例では、ジェネリック型の戻り値が必要であり、別の呼び出しを待つパスに戻り値を指定していません。

キーワードに関するMSDNリファレンスからの引用async、特にリターンタイプについて。

メソッドの完了時に意味のある値が返されない場合は、タスクを使用します。つまり、メソッドを呼び出すとタスクが返されますが、タスクが完了すると、タスクを待機しているawait式はすべてvoidと評価されます。

于 2012-08-24T19:13:01.153 に答える
8

あなたが与えた2番目の例では、何も返されませんでした。(理由については、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();
}

@ChrisHannon が言ったことに加えて、await documentationから。

...awaitを返すメソッド呼び出しの結果に が適用された場合Task<TResult>、await 式の型は ですTResultawaitを返すメソッド呼び出しの結果に が適用される場合Task、await 式の型は ですvoid。...

于 2012-08-24T19:09:01.890 に答える