Catch an exception thrown by an async void method(捕获异步 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.
推荐答案
读起来有点奇怪,但是是的,异常会冒泡到调用代码 - 但只有 如果你 await
或 Wait()
调用 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 方法引发的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:捕获异步 void 方法引发的异常


- WebMatrix WebSecurity PasswordSalt 2022-01-01
- C# 中多线程网络服务器的模式 2022-01-01
- 如何用自己压缩一个 IEnumerable 2022-01-01
- MoreLinq maxBy vs LINQ max + where 2022-01-01
- 良好实践:如何重用 .csproj 和 .sln 文件来为 CI 创建 2022-01-01
- C#MongoDB使用Builders查找派生对象 2022-09-04
- 输入按键事件处理程序 2022-01-01
- 带有服务/守护程序应用程序的 Microsoft Graph CSharp SDK 和 OneDrive for Business - 配额方面返回 null 2022-01-01
- 在哪里可以找到使用中的C#/XML文档注释的好例子? 2022-01-01
- Web Api 中的 Swagger .netcore 3.1,使用 swagger UI 设置日期时间格式 2022-01-01