2014-12-03 41 views
4

假設我有一個方法,它具有void返回類型,我需要await對此方法的操作。爲什麼一個void方法是異步的以便能夠等待?

public void someOperation() 
{ 
    //dostuff 
    var res = await someOtherOperation(); 
    //do some other stuff that needs res. 
} 

當我試圖編譯這段代碼,我得到了錯誤說someOperation必須申報async。我不明白爲什麼。我明白爲什麼如果該方法具有返回值,但在void時不在此處。甚至在等待操​​作對方法的返回值沒有影響的情況下也是如此。
這已經被作爲this問題的一部分提出,但我沒有找到我正在尋找的答案。 This guy僅提及:

async關鍵字啓用await關鍵字。因此,使用await 的任何方法都必須標記爲異步。

  • 首先,我不知道這意味着什麼是async關鍵字,可以await關鍵字。
  • 其次,重申我的問題,我不確定爲什麼它是需要
+2

1)您不能在未聲明爲'async'的方法中使用'await'運算符。因此它*使*操作員。 2)我不確定我明白你的問題是什麼,「爲什麼這是必需的?」這是必需的,因爲這是該語言的工作原理。究竟是什麼問題? – 2014-12-03 18:13:40

+0

我的意思是,它應該在那裏才符合現有設計?在這種情況下,設計師不想要例外嗎?因爲從我看它的方式來看它並不是必需的。如果調用者不需要知道它是'async',那麼該方法就可以正常工作。 – atoMerz 2014-12-03 18:16:46

回答

11

異步方法必須標記爲async。關鍵字asyncawait配對在一起,主要是出於向後兼容的原因; await是一個有效的標識符(不是關鍵字),所以當它添加到語言中時,它們還添加了async關鍵字。

或者,他們可能用了一個多字的關鍵字爲await,如await for。但是,語言設計團隊決定採用這種配對方式,因爲它清楚明確地標記了所有方法 - 編譯器和人員都可以更輕鬆地進行分析。

我有一個blog post on the subject,在鏈接Eric Lippert's definitive blog post以及討論blog commentsChannel9 forumsMSDN forums,當然right here on Stack Overflow的。

注意,一個async方法的無的結果值的天然返回類型Task,不voidvoidasync方法的非自然返回類型。所以,在看到「等待操作者必須是異步方法中的」當你默認反應的錯誤應該是將其標記爲async返回類型從voidTask改變:

public async Task someOperationAsync() 
{ 
    //dostuff 
    var res = await someOtherOperationAsync(); 
    //do some other stuff that needs res. 
} 

在此之前的最佳實踐之一在我的MSDN article on the subject:避免async voidasync void允許由事件處理程序的語言設計者(或代碼在邏輯上事件處理程序,如ICommand.Execute);任何其他用法都會導致問題。

11

我不明白爲什麼。

因爲您需要告訴編譯器您正在嘗試編寫異步方法。這正是你所引用文件的含義。

編譯器可以推斷,從你的方法是否包含任何await表達 - 但是這將意味着你可以註釋掉的方法之一線和整個方法的行爲將根本變化。 (想想異常處理,例如...)

它也提高了可讀性 - 這意味着任何讀你的代碼的人都知道這是一種從一開始就是異步方法。

所以基本上,答案是:

  • 因爲語言規範需要你你需要。編譯器正在實現語言規範。
  • 語言規範要求你,因爲它減少了驚喜元素。
+0

喬恩,有沒有這個副本?如果沒有,那麼這可能會成爲規範的「爲什麼我需要使我的方法'異步'」的問題。 – 2014-12-03 18:15:57

+0

@JohnSaunders:不是我知道的副手。有可能是,但我現在不知道它:) – 2014-12-03 18:16:50

+0

@JohnSaunders在我腦海中的標準參考是[Eric的博客文章](http://blogs.msdn.com/b/ericlippert/) archive/2010/11/11/whither-async.aspx)。它包括更深入地闡述喬恩在這裏總結的觀點以及其他幾個觀點,比如避免突然的變化(如果某人在5.0之前有一種叫做「await」的方法呢?)。 – Servy 2014-12-03 18:57:03

0

因爲它們必須在C#中配對工作。這是規則。

「async」關鍵字在該方法中啓用「await」關鍵字並更改方法結果的處理方式。這就是所有的異步關鍵字!它不會在線程池線程上運行此方法,或者執行任何其他類型的魔術。 async關鍵字只啓用await關鍵字(並管理方法結果)。