![](/img/trans.png)
[英]HttpClient.GetAsync(…) never returns when using await/async
[英]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);
它掛起在await
但http呼叫幾乎立即返回(通過提琴手確認); 好像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.