簡體   English   中英

在HttpClient中使用await的異步調用永遠不會返回

[英]Async call with await in HttpClient never returns

我正在Win8 CP上基於xaml的C# metro應用程序中進行調用; 此調用只是命中一個Web服務並返回JSON數據。

HttpMessageHandler handler = new HttpClientHandler();

HttpClient httpClient = new HttpClient(handler);
httpClient.BaseAddress = new Uri("http://192.168.1.101/api/");

var result = await httpClient.GetStreamAsync("weeklyplan");
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(WeeklyPlanData[]));
return (WeeklyPlanData[])ser.ReadObject(result);

它掛起在awaithttp呼叫幾乎立即返回(通過提琴手確認); 好像await被忽略了,它只是掛在那里。

在您詢問之前 - 是 - 打開了專用網絡功能。

任何想法為什么會掛起?

查看我的問題的答案 ,這似乎非常相似。

要嘗試的東西:在GetStreamAsync()返回的Task上調用ConfigureAwait(false) GetStreamAsync() 例如

var result = await httpClient.GetStreamAsync("weeklyplan")
                             .ConfigureAwait(continueOnCapturedContext:false);

這是否有用取決於你的代碼是如何被調用的 - 在我的情況下使用Task.GetAwaiter().GetResult()調用async方法Task.GetAwaiter().GetResult()導致代碼掛起。

這是因為GetResult()阻止當前線程,直到任務完成。 當任務完成時,它會嘗試重新進入啟動它的線程上下文,但不能,因為在該上下文中已經存在一個線程,該線程被GetResult()調用阻塞... 死鎖!

這篇MSDN文章詳細介紹了.NET如何同步並行線程 - 給出了我自己的問題的答案給出了一些最佳實踐。

只是抬頭 - 如果你錯過了在ASP.NET控制器中的頂級等待,並且你返回任務而不是結果作為響應,它實際上只是在嵌套的await調用中掛起而沒有錯誤。 這是一個愚蠢的錯誤,但是如果我看到這篇文章,它可能會讓我節省一些時間來查看代碼中的奇怪內容。

免責聲明:我不喜歡ConfigureAwait()解決方案,因為我發現它不直觀且難以記憶。 相反,我得出的結論是在Task.Run(()=> myAsyncMethodNotUsingAwait())中包裝無休止的方法調用。 這似乎100%工作,但可能只是一個競爭條件!? 我不太確定說實話是怎么回事。 這個結論可能是錯誤的,我冒這個StackOverflow點的風險,希望從評論中學習:-P。 請仔細閱讀!

我剛剛遇到了所描述的問題,並在此處找到了更多信息。

聲明是:“你不能調用異步方法”

await asyncmethod2()

來自阻止的方法

myAsyncMethod().Result

在我的情況下,我無法更改調用方法,它不是異步。 但我實際上並不關心結果。 我記得它也沒有工作刪除.Result並等待失蹤。

所以我這樣做了:

public void Configure()
{
    var data = "my data";
    Task.Run(() => NotifyApi(data));
}

private async Task NotifyApi(bool data)
{
    var toSend = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
    await client.PostAsync("http://...", data);
}

在我的情況下,我不關心調用非異步方法的結果,但我想在這個用例中很常見。 您可以在調用異步方法中使用結果。

暫無
暫無

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

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