c#のasync
/ await
キーワードを使用した非同期プログラミングのベストプラクティスに出くわしました(c#5.0は初めてです)。
与えられたアドバイスの1つは次のとおりです。
安定性:同期コンテキストを知る
...一部の同期コンテキストは非再入可能で、シングルスレッドです。つまり、コンテキスト内で一度に実行できる作業単位は1つだけです。この例は、Windows UIスレッドまたはASP.NET要求コンテキストです。これらのシングルスレッド同期コンテキストでは、自分でデッドロックするのは簡単です。シングルスレッドコンテキストからタスクを生成し、そのコンテキストでそのタスクを待つ場合、待機中のコードがバックグラウンドタスクをブロックしている可能性があります。
public ActionResult ActionAsync()
{
// DEADLOCK: this blocks on the async task
var data = GetDataAsync().Result;
return View(data);
}
private async Task<string> GetDataAsync()
{
// a very simple async method
var result = await MyWebService.GetDataAsync();
return result.ToString();
}
自分で分解しようとすると、メインスレッドはで新しいスレッドにスポーンしMyWebService.GetDataAsync();
ますが、メインスレッドはそこで待機しているので、で結果を待機しGetDataAsync().Result
ます。一方、データの準備ができていると言います。メインスレッドが継続ロジックを継続せず、継続結果の文字列を返すのはなぜGetDataAsync()
ですか?
上記の例でデッドロックが発生する理由を誰かが説明してもらえますか?私は問題が何であるかについて完全に無知です...