2012-08-02 125 views
13

我正在編寫一個封裝第三方Web服務調用的庫,並試圖使庫使用新的異步/等待功能。以下示例中async/await關鍵字的正確用法是什麼?嵌套異步/等待方法

public class MyApi 
{ 
    public Task<ApiResult> DoSomethingAsync() 
    { 
     return this.DoSomethingCore(); 
    } 

    public async Task<ApiResult> DoSomethingElseAsync() 
    { 
     return await this.DoSomethingCore(); 
    } 

    private async Task<ApiResult> DoSomethingCore() 
    { 
     var httpClient = new HttpClient(); 
     var httpResponseMessage = await httpClient.GetAsync("some url"); 
     var rawResultText = await httpResponseMessage.Content.ReadAsStringAsync(); 
     return new ApiResult(rawResultText);   
    } 
} 

要允許我的調用方等待DoSomethingAsync方法,該方法是否應該添加異步和等待關鍵字?或者是因爲它返回一個任務是好的嗎?這種嵌套有更好的模式嗎?

我認爲DoSomethingAsync方法是正確的方法去這裏,是否正確?我相信DoSomethingElseAsync在建立圖書館時似乎是錯誤的方法。

+0

C#5.0不存在,下一個版本是4.5,你碰巧意味着什麼? – 2012-08-02 15:13:34

+9

@Ramhound - 下一個CLR是4.5,下一個語言_is_ C#5 – 2012-08-02 15:19:45

回答

8

任何Task都可以等待,無論它來自何處。

我不知道爲什麼DoSomethingAsync只是調用DoSomethingCore,因爲DoSomethingAsync可以很容易地被async和使用await

還有一個general rule,您應該在庫方法中使用ConfigureAwait(false)

編輯:如果你不需要使用await,那麼不要使方法asyncasync會增加一些開銷(檢查通道9爲斯蒂芬Toub的異步性能視頻的禪宗)。如果你只能返回一個Task(如DoSomethingAsync),那麼就這樣做。

+0

DoSomethingAsync調用DoSomethingCore,因爲在我的真實場景中,我有兩個類似的公共方法,它們使用核心方法共享功能。 我將查看ConfigureAwait方法,因爲我之前沒有見過。 – 2012-08-02 18:57:31

+0

我已經添加了DoSomethingElseAsync()方法來更好地解釋我所困惑的內容。我相信你已經充分解釋了這一點,並且DoSomethingAsync()方法是一種庫方法。 – 2012-08-02 19:02:13

+0

好的。查看更新的答案。 – 2012-08-02 21:03:23

0

下面的製劑是功能性的,但是很可能會造成額外的開銷(由於具有用於附加異步二次回調/等待方法。)

public async Task<ApiResult> DoSomethingElseAsync() 
{ 
    return await this.DoSomethingCore(); 
} 

所以,很簡單直接返回任務,因爲你可以總是在別處等待該任務,而不必將該方法實施爲「異步」。異步/等待很像使用「收益回報」;它會執行一些編譯器魔術來實現'yielding',但枚舉本身並不關心你如何實現它。同樣,只要候選人能夠等待,「等待」電話並不在乎等待的工作。