Task.Result は .GetAwaiter.GetResult() と同じですか? 質問する

Task.Result は .GetAwaiter.GetResult() と同じですか? 質問する

最近、非同期メソッドを多く使用するコードを読みましたが、場合によってはそれらを同期的に実行する必要があります。コードでは次の処理が行われます。

Foo foo = GetFooAsync(...).GetAwaiter().GetResult();

これは同じですか

Foo foo = GetFooAsync(...).Result;

ベストアンサー1

Task.GetAwaiter().GetResult()は、例外を でラップするのではなく、伝播するため、Task.Waitやよりも好まれます。ただし、3 つの方法はすべて、デッドロックやスレッド プールの枯渇の問題を引き起こす可能性があります。これらはすべて避けて を使用してください。Task.ResultAggregateExceptionasync/await

以下の引用ではTask.Wait、なぜ がTask.Result例外伝播の動作を単純に含まないのかを説明していますTask.GetAwaiter().GetResult()(「非常に高い互換性バー」のため)。

前に述べたように、私たちは非常に高い互換性基準を設けているため、互換性を破る変更を避けてきました。そのため、 はTask.Wait常にラップするという元の動作を維持しています。ただし、 が採用している同期ブロッキングに似た動作が必要な高度な状況では、元Task.Waitの例外を に格納するのではなく、ラップせずに伝播させたい場合がありAggregateExceptionます。これを実現するには、タスクの awaiter を直接ターゲットにすることができます。「 」と記述するとawait task;、コンパイラはそれをTask.GetAwaiter()メソッドの使用に変換し、 メソッドを持つインスタンスを返しますGetResult()。障害が発生したタスクで使用すると、GetResult()は元の例外を伝播します (これが「await task;」の動作を取得する方法です)。したがって、task.GetAwaiter().GetResult()この伝播ロジックを直接呼び出す場合は「 」を使用できます。

https://devblogs.microsoft.com/pfxteam/task-exception-handling-in-net-4-5/

GetResult」は実際には「タスクにエラーがないか確認する」という意味です

一般的に、私は非同期タスクで同期ブロックを回避するよう最善を尽くします。しかし、そのガイドラインに違反する状況もいくつかあります。そのようなまれな状況では、GetAwaiter().GetResult()タスク例外を にラップするのではなく、それを保持するという方法を好みますAggregateException

https://blog.stephencleary.com/2014/12/a-tour-of-task-part-6-results.html

おすすめ記事