使用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. */ } }
因此,基本上,我希望异步代码中的异常冒充到我的调用代码中,即使有可能的话。
阅读起来有点奇怪,但是可以,该异常会冒泡到调用代码中-但仅 当您await或Wait()对的调用Foo时才 如此 。
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. */ } }
异步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非常好-它讨论了编译器为实现此魔术而采取的步骤。