非同期voidメソッドによってスローされた例外をキャッチする 質問する

非同期voidメソッドによってスローされた例外をキャッチする 質問する

Microsoft for .NET の async CTP を使用すると、呼び出しメソッドで async メソッドによってスローされた例外をキャッチすることは可能ですか?

public async void Foo()
{
    var x = await DoSomethingAsync();

    /* Handle the result, but sometimes an exception might be thrown.
       For example, DoSomethingAsync gets data from the network
       and the data is invalid... a ProtocolException might be thrown. */
}

public void DoFoo()
{
    try
    {
        Foo();
    }
    catch (ProtocolException ex)
    {
          /* The exception will never be caught.
             Instead when in debug mode, VS2010 will warn and continue.
             The deployed the app will simply crash. */
    }
}

つまり、基本的には、可能であれば、非同期コードからの例外を呼び出しコードにバブルアップさせたいのです。

ベストアンサー1

読むと少し奇妙に思えますが、例外は呼び出しコードにバブルアップされます - ただし、あなたawaitまたは のWait()呼び出しのFoo場合のみです。

public async Task Foo()
{
    var x = await DoSomethingAsync();
}

public async void DoFoo()
{
    try
    {
        await Foo();
    }
    catch (ProtocolException ex)
    {
          // The exception will be caught because you've awaited
          // the call in an async method.
    }
}

//or//

public void DoFoo()
{
    try
    {
        Foo().Wait();
    }
    catch (ProtocolException ex)
    {
          /* The exception will be caught because you've
             waited for the completion of the call. */
    }
} 

スティーブン・クリアリーが書いたようにAsync/Await - 非同期プログラミングのベストプラクティス:

非同期 void メソッドには、異なるエラー処理セマンティクスがあります。非同期 Task または非同期 Task メソッドから例外がスローされると、その例外はキャプチャされ、Task オブジェクトに配置されます。非同期 void メソッドでは Task オブジェクトが存在しないため、非同期 void メソッドからスローされた例外は、非同期 void メソッドの開始時にアクティブだった SynchronizationContext で直接発生します。

.NET がメソッドを同期的に実行することにした場合、を使用するとWait()アプリケーションがブロックされる可能性があることに注意してください。

この説明http://www.interact-sw.co.uk/iangblog/2010/11/01/csharp5-async-exceptionsかなり良いです - この魔法を実現するためにコンパイラが実行する手順について説明しています。

おすすめ記事