私のコードは、非同期メソッドと例外処理を組み合わせています。コードは非常に単純であり、すべてのタスクが待っていると何のasync void
方法はありません:例外が飲み込まれたため、例外をスローしません、このメソッドを待ち非同期メソッドの例外処理が例外をキャッチしない驚くべきケース
async Task DoWorkSafelyWithStateMachine()
{
try
{
await DoWorkThatMightThrowException();
}
catch (Exception exception)
{
Console.WriteLine("With state machine: " + exception.Message);
}
}
は:
await DoWorkSafelyWithStateMachine(); // No exception thrown
しかし、コードはありません例外を常にキャッチするとは限りません。この方法は全く非同期ステートマシンは、コンパイラによって作成されていない少し異なる方法で書かれているときに問題が生じる:
Task DoWorkSafelyWithoutStateMachine()
{
try
{
return DoWorkThatMightThrowException();
}
catch (Exception exception)
{
Console.WriteLine("Without state machine: " + exception.Message);
return Task.CompletedTask;
}
}
方法をasync
で飾られていないと何もメソッド内待望されていません。代わりに、try
内のメソッドによって返されたタスクが呼び出し側に返されます。しかし、私の経験では、コンパイラの魔法はどういうわけか、まだtry
のメソッドが例外をスローすると、例外ハンドラによって捕捉されることを保証します。まあ、明らかにそれは常に真実ではありません。
同じメソッドのこれらの2つのバリエーションをテストするには、私はDoWorkThatMightThrowException
例外をスローします。この方法は、メソッドの本体でawait
を使用する必要がない場合、それがまたは非同期ステートマシンもしなくても実装できます。
async Task DoWorkThatMightThrowExceptionWithStateMachine()
{
throw new Exception("With state machine");
await Task.CompletedTask;
}
Task DoWorkThatMightThrowExceptionWithoutStateMachine()
{
throw new Exception("Without state machine");
return Task.CompletedTask;
}
DoWorkSafelyWithoutStateMachine
からDoWorkThatMightThrowExceptionWithStateMachine
を呼び出すと例外がスローされたキャッチしていないことを私が発見しました。他の3つの組み合わせは例外をキャッチします。特に、どちらのメソッドにも非同期状態マシンが含まれていないバージョンでは例外が発生しますが、誤ってこのコードを外挿すると、コードの一部に微妙なエラーが発生するという不幸な結果になります。
| Throw + state machine | Throw - state machine | --------------------------+-----------------------+-----------------------+ Try/catch + state machine | Caught | Caught | Try/catch - state machine | Not caught | Caught |
私は、私はいつもawait
にtry
ブロック(テーブルの最初の行)内のタスクを持っていることを学びました。この実験を行います。しかし、私はテーブルの2番目の行の不一致を理解していません。この現象を説明してください。それはどこに文書化されていますか?これに関する情報を検索することは容易ではありません。タスクが待たれていないために例外が「失われている」という基本的な問題は、検索結果を支配します。
質問はしていません。 – Servy
@セイビー:私は黙示的な質問に理解できないと思った。しかし、私はフレーズを少し修正し、さらに疑問符を追加しました。 –
上記の方法とそれらがどのように実行されるのかを[MCVE]に見ていただければ幸いです。あなたのコードは...奇妙なようです。あなたは*タスク内でスローされた例外をどのように管理するのかを誤解しているかもしれません。すべての作品をまとめることなく伝えるのは難しい。 – Will