2013-04-11 62 views
2

任何人都可以解釋爲什麼c#5中的異步函數需要至少有1個等待?我找不到明確的理由/解釋。爲什麼沒有等待的異步函數會導致編譯器警告?

根據需要,我的意思是編譯器會在異步函數內部沒有任何等待調用時發出警告,但不會引發編譯錯誤。

this answer

類似地,方法標記爲異步必須至少有一個AWAIT。在等待時,運行時將保存當前線程的狀態和調用堆棧,進行異步調用,並退回到運行時的消息循環以處理下一條消息並使應用程序響應。當異步操作完成時,在下一個調度機會中,啓動異步操作的調用堆棧被推入並繼續,就好像調用是同步的。

但是從MSDN:

如果方法不包含等待表達式或語句,然後同步執行。編譯器警告會提醒您任何不包含await的異步方法,因爲這種情況可能表示出現錯誤。

什麼類型的錯誤發生,值得這是一個編譯器警告而不只是推薦的用法?

+1

是不是[問 - 之前回答](http:// stackoverflow。com/questions/12016567/using-async-without-await)幾次? – 2013-04-11 10:05:11

回答

6

MSDN對此警告有很好的描述:Compiler Warning (level 1) CS4014。從它的好報價將是:

在大多數情況下,這種行爲是不是你所期望的。

我認爲這個警告存在的主要原因是async/await並不是真的很明顯,開發人員通常會犯下如下所述的錯誤。

比如你有一個方法,它做一些重幾秒鐘:

public int DoSomething() 
{ 
    int sum = 0; 

    for (int i = 0; i < 10; i++) 
    { 
     sum += i; 
     Thread.Sleep(1000); 
    } 

    return sum; 
} 

你聽說過asyncawait的地方,你想嘗試一下。這是人們經常認爲他們(不經常也許,但我認爲這是它是如何工作之前,我閱讀更多的文檔,所以我們可以指望至少我)移動的一切背景:

public async Task<int> DoSomething() 
{ 
    int sum = 0; 

    for (int i = 0; i < 10; i++) 
    { 
     sum += i; 
     Thread.Sleep(1000); 
    } 

    return sum; 
} 

你認爲這個問題是解決了,但警告,告訴你,沒有await你不應該使用async,因爲它只是什麼都不做,你的所有代碼將同步運行,與async最後一個示例是類似於下面的代碼:

public Task<int> DoSomething() 
{ 
    int sum = 0; 

    for (int i = 0; i < 10; i++) 
    { 
     sum += i; 
     Thread.Sleep(1000); 
    } 

    return Task.Result<int>(sum); 
} 

如果你在同一個環境中做所有事情,這就是所謂的m ethod。

所以這個警告的主要原因我想讓人們知道,他們可能使用async錯誤,這是閱讀文檔的時候。

相關問題