非同期 void
メソッドの例外処理
非同期プログラミングに Microsoft の Async CTP を使用する場合、非同期 void
メソッドの例外処理動作を理解することが重要です。次のシナリオを考えてみましょう:
<code class="language-csharp">public async void Foo() { var x = await DoSomethingAsync(); } public void DoFoo() { try { Foo(); } catch (ProtocolException ex) { // 异常将永远不会被捕获。 } }</code>
問題は、非同期メソッド DoFoo
でスローされた例外を呼び出し側メソッド Foo
でキャッチできるかということです。
答え: はい (ただし前提条件があります)
例外は呼び出しコードにバブルアップしますが、これは await
または Wait()
Foo
の呼び出しが必要な場合に限られます。コードを次のように変更します:
<code class="language-csharp">public async Task Foo() { var x = await DoSomethingAsync(); } public async void DoFoo() { try { await Foo(); } catch (ProtocolException ex) { // 异常将被捕获,因为它是一个异步方法。 } } public void DoFoo() { try { Foo().Wait(); } catch (ProtocolException ex) { // 异常将被捕获,因为调用被等待。 } }</code>
これにより、呼び出しコードでの例外処理が可能になります。
ただし、非同期プログラミングの権威である Stephen Cleary 氏が次のように警告していることに注意することが重要です。
さらに、.NET がメソッドを同期的に実行することを決定した場合、「非同期
void
メソッドには、異なるエラー処理セマンティクスがあります。非同期Task
または非同期Task<T>
メソッドから例外がスローされると、例外はキャッチされ、Task
オブジェクトに配置されます。非同期void
メソッドの場合、Task
オブジェクトがないため、非同期void
メソッドからスローされた例外は、非同期void
メソッドが開始されたときにアクティブだったSynchronizationContext
で直接発生します。
を使用してタスクの完了を待機すると、アプリケーションがブロックされる可能性があります。 Wait()
以上がAsync Void メソッドでスローされた例外は、メソッドの呼び出しによってキャッチできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。