首頁 > 後端開發 > C++ > 為什麼在 ASP.NET 中使用 Await/Async 時我的 HttpClient.GetAsync 呼叫掛起?

為什麼在 ASP.NET 中使用 Await/Async 時我的 HttpClient.GetAsync 呼叫掛起?

DDD
發布: 2025-01-25 13:23:08
原創
747 人瀏覽過

Why Does My HttpClient.GetAsync Call Hang When Using Await/Async in ASP.NET?

ASP.NET 中使用 Await/Async 時 HttpClient.GetAsync(...) 掛起的原因

在 ASP.NET 中,只有一個執行緒可以同時處理一個請求。雖然可以進行並行處理,但只有一個執行緒擁有請求上下文。此執行緒管理由 ASP.NET SynchronizationContext 控制。

當等待一個 Task 時,方法通常會在捕獲的 SynchronizationContext(如果不存在則為 TaskScheduler)上恢復。這與非同步控制器操作的預期行為一致。

測試案例 5 中的問題

Test5Controller.Get 中的死鎖是由於以下順序造成的:

  1. 在 ASP.NET 請求上下文中呼叫 HttpClient.GetAsync。
  2. HttpClient.GetAsync 發送 HTTP 請求並傳回一個未完成的 Task。
  3. AsyncAwait_GetSomeDataAsync 等待 Task 並傳回一個未完成的 Task,因為請求仍在進行中。
  4. Test5Controller.Get 阻塞目前線程,直到 AsyncAwait_GetSomeDataAsync 傳回的 Task 完成。
  5. 接收到 HTTP 回應,HttpClient.GetAsync Task 完成。
  6. AsyncAwait_GetSomeDataAsync 嘗試在 ASP.NET 請求上下文中復原。
  7. 發生死鎖,因為在 Test5Controller.Get 中阻塞的執行緒仍然持有請求上下文。

解決問題

可以實作一些最佳實務來避免類似的問題:

  • 在庫非同步方法中使用 ConfigureAwait(false) 來在 ASP.NET 請求上下文之外調度延續。
  • 透過使用 await 而不是 GetResult 或 Task.Wait 來避免阻塞 Task。

結論

了解 SynchronizationContext 的作用以及使用 async/await 技術的最佳實踐,可以確保在 ASP.NET 中使用非同步程式碼時高效且無死鎖的操作。

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

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