簡體   English   中英

在等待任務返回之前會發生什么?

[英]What happens when you await a Task before returning it?

我正在嘗試新的async和await關鍵字。 我生成了以下異步函數:

private async static Task<string> GetStringAsync(string pageAddress)
{
    HttpClient client = new HttpClient();
    return client.GetStringAsync(pageAddress);
}

我知道我正在返回一個Task<String> ,可以等待另一個方法的結果。 這種方法很好。 我的問題是當我用以下內容替換上面函數的第二行時會發生什么(在引擎蓋下)(請注意await關鍵字的介紹):

return await client.GetStringAsync(pageAddress);

該功能的行為方式完全相同! 記住該函數返回Task<string>而不是string 這里的await關鍵字是退化嗎? 編譯器是否只是從我的代碼中刪除它?

鑒於您目前的理解水平,這個問題的答案太大了,無法在此發布。 你應該做的是先閱讀我的MSDN文章,然后閱讀Mads的MSDN文章; 它們是該功能的初學者入門,Mads描述了它是如何實現的。 你可以在這里找到鏈接:

http://blogs.msdn.com/b/ericlippert/archive/2011/10/03/async-articles.aspx

然后,如果您對該功能的基礎理論感興趣,您應該首先閱讀我關於延續傳遞風格的所有文章:

http://blogs.msdn.com/b/ericlippert/archive/tags/continuation+passing+style/

從底部開始。 一旦理解了延續的概念,您就可以閱讀我關於如何設計異步功能的系列文章:

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

正如Eric Lippert指出的那樣,第一個版本將無法編譯; 您必須刪除async關鍵字,否則您將收到類型錯誤。

這是一個有用的心理模型,關於asyncawait關鍵字如何與返回類型一起使用:

  • async方法返回的任何值T都“包裝”到Task<T>
  • 當應用於Task<T>await關鍵字(您可以將其視為運算符)將“解包”它,從而產生類型為T的值。

現在,這是一種極端的簡化; 實際發生的事情更復雜。 例如,這種簡化會跳過await如何使用當前的SynchronizationContext :在第二個示例中,該方法將嘗試在await完成后返回到原始上下文,因此如果該上下文繁忙,您將觀察到不同的行為。

但在大多數情況下,這兩個例子幾乎相同。 由於async狀態機並在上下文中恢復,第二個效率較低。

我有一個async / await介紹 ,你可能會覺得有幫助; async文章中,我嘗試以一種不太復雜但實際上也不正確的方式解釋async :)

埃里克顯然是這里的專家,他的建議很合理,但回答你的具體問題:

在第一個版本中, async的方法關鍵字是不相關的,你GetStringAsync方法返回相同的Task<string> awaitable多數民眾贊成由返回client.GetStringAsync

在第二個版本中,方法上的async關鍵字是必需的,因為您在方法中使用await並且await關鍵字創建並返回一個單獨的Task<string> ,等待來自client.GetStringAsync完成。 發生這種情況時, await client.GetStringAsync異步獲取的字符串,該字符串作為異步方法的結果返回。

所以對於GetStringAsync的調用者來說,它們在功能上是相同的,但第一個版本更清晰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM