async
/await
および HttpClient.GetAsync(...)
のデッドロック: 解決策問題: ASP.NET HttpClient.GetAsync(...)
メソッド内で async
を使用すると、デッドロックが発生する可能性があります。これは、ASP.NET のシングルスレッド要求処理モデルが HttpClient
の非同期の性質と競合するために発生します。 await
が実行を一時停止すると、スレッドは解放されますが、タスクを再開すると、別のリクエストによってすでに占有されている同じスレッドを再取得しようとする可能性があり、停止が発生します。
デッドロックを理解する:
httpClient.GetAsync
は不完全な Task
を返します。await
は、Task
が終了するまで現在のスレッドを一時停止します。Task
は ASP.NET 要求コンテキスト内で再開しようとしますが、コンテキストはすでに使用されています。主要なソリューション:
ConfigureAwait(false)
: この重要なメソッドは、Task
の継続が元のコンテキスト (ASP.NET 要求スレッドなど) にスケジュールされるのを防ぎます。これにより、コンテキスト関連のデッドロックの可能性が排除されます。
ブロックの回避: 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 での非同期プログラミングとデッドロックを回避する方法をより深く理解するには、次のリソースを参照してください。
以上がASP.NET で `await`/`async` を使用すると `HttpClient.GetAsync(...)` がハングするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。