一尘不染

捕获异步void方法引发的异常

c#

使用Microsoft .NET的异步CTP,是否有可能在调用方法中捕获由异步方法引发的异常?

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. */
    }
}

因此,基本上,我希望异步代码中的异常冒充到我的调用代码中,即使有可能的话。


阅读 341

收藏
2020-05-19

共1个答案

一尘不染

阅读起来有点奇怪,但是可以,该异常会冒泡到调用代码中-但仅 当您awaitWait()对的调用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. */
    }
}

异步void方法具有不同的错误处理语义。从异步Task或异步Task方法抛出异常时,将捕获该异常并将其放置在Task对象上。使用异步void方法时,没有Task对象,因此从异步void方法抛出的任何异常都将直接在启动异步void方法时处于活动状态的SynchronizationContext上引发。-
https://msdn.microsoft.com/en-
us/magazine/jj991977.aspx

请注意,如果.Net决定同步执行方法,则使用Wait()可能会导致应用程序阻塞。

这个说明http://www.interact-sw.co.uk/iangblog/2010/11/01/csharp5-async-
exceptions非常好-它讨论了编译器为实现此魔术而采取的步骤。

2020-05-19