首頁 > 後端開發 > C++ > 為什麼在 ASP.NET 中使用 `await`/`async` 時 `HttpClient.GetAsync(...)` 掛起?

為什麼在 ASP.NET 中使用 `await`/`async` 時 `HttpClient.GetAsync(...)` 掛起?

Mary-Kate Olsen
發布: 2025-01-25 13:28:10
原創
284 人瀏覽過

Why Does `HttpClient.GetAsync(...)` Hang When Using `await`/`async` in ASP.NET?

ASP.NET async/awaitHttpClient.GetAsync(...) 死鎖:解決方案

問題: 在 ASP.NET HttpClient.GetAsync(...) 方法中使用 async 可能會導致死鎖。發生這種情況是因為 ASP.NET 的單線程請求處理模型與 HttpClient 的異步性質發生衝突。 當 await 暫停執行時,線程被釋放,但恢復任務可能會嘗試重新獲取已被另一個請求佔用的同一線程,從而導致停滯。

理解死鎖:

  1. httpClient.GetAsync 返回不完整的 Task
  2. await 暫停當前線程,直到 Task 完成。
  3. Task 嘗試在 ASP.NET 請求上下文中恢復,但該上下文已在使用中。
  4. 導致僵局。

關鍵解決方案:

  1. ConfigureAwait(false): 這個關鍵方法可以防止 Task 的繼續被安排回原始上下文(例如 ASP.NET 請求線程)。這消除了與上下文相關的死鎖的可能性。

  2. 避免阻塞:始終使用await而不是像GetResult()這樣的方法,這些方法會在Task上同步阻塞,直接導致死鎖。

代碼示例:

有問題的代碼:

<code class="language-csharp">public async Task<string> GetSomeDataAsync()
{
    var httpClient = new HttpClient();
    var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead);
    return result.Content.Headers.ToString();
}</code>
登入後複製

更正代碼:

<code class="language-csharp">public async Task<string> GetSomeDataAsync()
{
    var httpClient = new HttpClient();
    var result = await httpClient.GetAsync("http://stackoverflow.com", HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
    return result.Content.Headers.ToString();
}</code>
登入後複製

進一步閱讀:

要更深入地了解 .NET 中的異步編程以及如何避免死鎖,請參閱以下資源:

透過在非同步方法中一致使用 ConfigureAwait(false),可以有效防止這些死鎖並確保 ASP.NET 應用程式的順利運作。

以上是為什麼在 ASP.NET 中使用 `await`/`async` 時 `HttpClient.GetAsync(...)` 掛起?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板