[英]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/
從底部開始。 一旦理解了延續的概念,您就可以閱讀我關於如何設計異步功能的系列文章:
正如Eric Lippert指出的那樣,第一個版本將無法編譯; 您必須刪除async
關鍵字,否則您將收到類型錯誤。
這是一個有用的心理模型,關於async
和await
關鍵字如何與返回類型一起使用:
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.