2012-08-24 76 views
6

希望這不是重複,但有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(); 
    } 
+0

@LB \ *「*應*回報'Task'和... –

回答

8

非通用Task類型有點等同於一個可等待的void方法。就像一個無效的方法,你不能返回返回類型爲Task,這就是爲什麼第一個例子編譯的方法的任何東西。然而,第二個例子期望泛型類型的返回值,並且您沒有在等待另一個調用的路徑中提供它。

MSDN reference引用async關鍵字,具體關於返回類型。

如果完成方法爲 時沒有返回有意義的值,則使用任務。也就是說,對該方法的調用會返回一個Task,但是當任務完成時,任何等待Task 的await表達式都將被計算爲void。

+2

我的理解是,AWAIT表達式的值*適用於*返回值,所以它不等同於返回Void,然而它本身就是'System.Void'。 –

+1

確實,這個方法確實隱含地返回了一個你可以等待的'Task',它相當於void,因爲你不允許返回一個自己的方法的值,並且任何東西都不能作爲等待方法的結果賦值。在任務'的情況下,你返回的'T'可以從等待中分配(例如'var value = await SomeCall ();')。 –

+0

謝謝,很好的解釋。它現在總是有意義,但最初是abstr層這個建築物的行動讓我失望了。 – HolySamosa

7

在第二個例子中,你給了你沒有任何回報。 (見克里斯漢農的答案爲什麼)。

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表達式的類型是TResult方法調用的結果。如果將await應用於返回Task的方法調用的結果,則await表達式的類型爲void。 ...

+0

謝謝你,大衛。我很欣賞的例子。 – HolySamosa

相關問題