异步void
方法的异常处理
在使用微软的异步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警告说:
“异步
void
方法具有不同的错误处理语义。当从异步Task
或异步Task<T>
方法抛出异常时,该异常会被捕获并放置在Task
对象上。对于异步void
方法,没有Task
对象,因此从异步void
方法抛出的任何异常都将直接在启动异步void
方法时活动的SynchronizationContext
上引发。”
此外,使用Wait()
等待任务完成可能会阻塞应用程序,如果.NET决定同步执行该方法的话。
以上是Async Void 方法中抛出的异常可以通过调用方法捕获吗?的详细内容。更多信息请关注PHP中文网其他相关文章!