捕获异步 void 方法引发的异常
- 作者: 想念你的腿想念你的嘴
- 来源: 51数据库
- 2023-02-08
问题描述
使用 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.51sjk.com/Upload/Articles/1/0/342/342819_20230208102204234.jpg 非常好 - 它讨论了编译器为实现这一魔力所采取的步骤.
This explanation http://www.51sjk.com/Upload/Articles/1/0/342/342819_20230208102204234.jpg is pretty good - it discusses the steps the compiler takes to achieve this magic.
- C#通过fleck实现wss协议的WebSocket多人Web实时聊天(附源码)
- 团队城市未满足要求:MSBuildTools12.0_x86_Path 存在
- 使用 MSBuild.exe 在发布模式下构建 C# 解决方案
- 当我发布 Web 应用程序时,AfterPublish 脚本不运行
- 构建时 T4 转换的产品仅在下一个构建中使用
- ASP.NET Core Application (.NET Framework) for Windows x64 only error in project.assets.json
- 新的 .csproj 格式 - 如何将整个目录指定为“链接文件"到子目录?
- 如何将条件编译符号(DefineConstants)传递给 msbuild
- MSBuild 支持 Visual Studio 2017 RTM 中的 T4 模板
- NuGet 包还原找不到包,没有源
