捕获异步 void 方法引发的异常 [英] Catch an exception thrown by an async void method

查看:42
本文介绍了捕获异步 void 方法引发的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Microsoft for .NET 的异步 CTP,是否可以在调用方法中捕获异步方法抛出的异常?

Using the async CTP from Microsoft for .NET, is it possible to catch an exception thrown by an async method in the calling method?

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

所以基本上我希望异步代码中的异常冒泡到我的调用代码中如果这是可能的话.

So basically I want the exception from the async code to bubble up into my calling code if that is even possible at all.

推荐答案

读起来有点奇怪,但是是的,异常会冒泡到调用代码 - 但只有 如果你 awaitWait() 调用 Foo.

It's somewhat weird to read but yes, the exception will bubble up to the calling code - but only if you await or Wait() the call to 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. */
    }
} 

正如 Stephen Cleary 在 Async/Await - 异步编程最佳实践:

As Stephen Cleary wrote in Async/Await - Best Practices in Asynchronous Programming:

Async void 方法具有不同的错误处理语义.当异步任务或异步任务方法抛出异常时,会捕获该异常并将其放置在任务对象上.对于 async void 方法,没有 Task 对象,因此从 async void 方法抛出的任何异常都将直接在 async void 方法启动时处于活动状态的 SynchronizationContext 上引发.

Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started.

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

Note that using Wait() may cause your application to block, if .NET decides to execute your method synchronously.

这个解释http://www.interact-sw.co.uk/iangblog/2010/11/01/csharp5-async-exceptions 非常好 - 它讨论了编译器为实现这一魔力所采取的步骤.

This explanation http://www.interact-sw.co.uk/iangblog/2010/11/01/csharp5-async-exceptions is pretty good - it discusses the steps the compiler takes to achieve this magic.

这篇关于捕获异步 void 方法引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆