この質問にはすでに答えがあります。
私は単純化した構造を持っています、そしてそれがなぜうまくいくのか(あるいはうまくいかないのか)私はそれがうまくいくべきだと思う方法を理解するのに苦労しています。
基本的に2つの方法があります
private async void DoStuff()
{
try {
AuthenticationStuff();
}catch(UnauthorizedAccessException){
UI.Display("AMAGAD!");
}
}
private async void AuthenticationStuff()
{
var user = GetUser();
if(user == null) throw new UnauthorizedAccessException();
DoMoreAuthenticationStuff();
}
今問題は例外が決して達しないということですDoStuff()
メソッドのハンドラ私の最初の本能は「ねえ、それは非同期メソッドだ、私はそれを待たなければならない」ということでした、しかし私はそれをすることができないようですTask<void>
。
ここで何が起こっているのか理解しようとしています。例外がハンドラに送られないのではなく、デバッガが次のように中断します。"DoMoreAuthenticationStuff()
"例外のないエラーが発生しましたか?
によって発生した例外async void
方法は直接SynchronizationContext
メソッドが開始された時点ではアクティブでした。これがあなたが避けるべき理由の一つです。async void
。私は私のMSDNの記事でこれと他の理由をカバーします非同期プログラミングのベストプラクティス。
このような例外をキャッチするには、async void
メソッドasync Task
そしてawait
返されたタスク
私の最初の本能は「ねえ、それは非同期メソッドです、私は待たなければならないということでした それは "しかし、私はそれを行うことはできませんどちらか明らかにasyncのvoidが異なるように 非同期タスクから。
あなたはただ言うことができますasync Task MyMethod()
。その後、その結果を待って例外を伝播させる(そして完了を待つ)ことができます。
詳細についてはStephen Clearyの回答もご覧ください。