我正在嘗試從在 IIS 8.5 上運行的 ASP.NET 應用程序中對另一臺服務器進行 HTTP 調用。首先,我從 Microsoft 的一篇文章Call a Web API From a .NET Client (C#) 中得到了一些提示。我可以很容易地看到他們如何在那里進行 HTTP 調用的模式;僅顯示一個縮短的示例: static async Task<Product> GetProductAsync(string path) { HttpResponseMessage response = await client.GetAsync(path); if (response.IsSuccessStatusCode) { // retrieve response payload ... = await response.Content.ReadAsAsync<...>(); } // do something with data }很簡單,我想,所以我很快為我的應用程序編寫了一個類似的方法(請注意,ReadAsAsync擴展方法似乎需要一個額外的庫,所以我選擇了一個內置的、更抽象的,但在其他方面可能是類似的方法): private async Task<MyInfo> RetrieveMyInfoAsync(String url) { var response = await HttpClient.GetAsync(url); response.EnsureSuccessStatusCode(); var responseBody = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<MyInfo>(responseBody); }不幸的是,調用此方法會導致我的應用程序掛起。調試時,事實證明await調用GetAsync永遠不會返回。摸索了一會兒后,我碰上了一個遙控類似的問題,在其評論部分,我發現一個很有意思的建議,通過B君:刪除所有異步內容并確保它有效。所以我試了一下: private Task<MyInfo> RetrieveMyInfoAsync(String url) { return HttpClient.GetAsync(url).ContinueWith(response => { response.Result.EnsureSuccessStatusCode(); return response.Result.Content.ReadAsStringAsync(); }).ContinueWith(str => JsonConvert.DeserializeObject<MyInfo>(str.Result.Result)); }有點令人驚訝(對我來說),這是有效的。 GetAsync在不到一秒的時間內返回來自其他服務器的預期響應。現在,同時使用 AngularJS,我對response.Result.Content和 之類的東西感到有點失望str.Result.Result。在 AngularJS 中,我希望上面的調用只是類似于:$http.get(url).then(function (response) { return response.data;});即使我們不考慮 JavaScript 中發生的自動 JSON 反序列化,AngularJS 代碼仍然更容易,因為 egresponse沒有被包裝成一個承諾或類似的東西,我也不會像Task<Task<...>>從延續函數中返回另一個承諾那樣結束結構.因此,我對不得不使用這種ContinuesWith語法而不是更具可讀性的 async-await 模式不太滿意,如果后者只是有效的話。我在 C# HTTP 調用的 async-await 變體中做錯了什么?
1 回答

神不在的星期二
TA貢獻1963條經驗 獲得超6個贊
因此,根據對ConfigureAwait(false)
您的問題有幫助的事實判斷,請從 Stephen Cleary 的博客中閱讀這些內容:http : //blog.stephencleary.com/2012/07/dont-block-on-async-code.html
這家伙幾乎是async
專家(他在 C# Cookbook 書中寫了并發),所以無論我能說什么,他都可能解釋得更好。基本上你擋住了ASP.NET線程的地方,也許不是用await
所有的方式,而是Wait
,Result
還是GetResult()
。您應該能夠使用該博客自行診斷問題。
什么ConfigureAwait(false)
做的是它并沒有抓住當前背景下,這樣的HTTP請求被執行(正確的)其他地方比在ASP.NET背景下,防止死鎖。
編輯:
GetAwaiter().GetResult()
從您的評論來看,是什么導致了問題。如果您將其更改為await
和調用方法,async
您可能會解決所有問題。
由于 C# 7.0 和async Task Main()
方法支持,因此真的沒有理由await
在應用程序代碼中阻塞而不是使用。
- 1 回答
- 0 關注
- 215 瀏覽
添加回答
舉報
0/150
提交
取消