【发布时间】:2015-12-16 04:55:59
【问题描述】:
我有一长串调用,最终调用另一个程序集中的异步函数。我希望这个函数被同步执行,它可能抛出一个异常,我想把它传播到调用链上。
下面的 sn-p 最小限度地再现了这个场景:
static Task<int> Exc()
{
throw new ArgumentException("Exc");
return Task.FromResult(1);
}
static async void DoWork()
{
await Exc();
}
static void Main(string[] args)
{
try
{
DoWork();
}
catch (Exception e)
{
Console.WriteLine("Caught {0}", e.Message);
}
}
此代码将导致崩溃,因为从Exc 抛出的异常不会传播回Main。
我有什么办法可以让Exc 中的catch 块处理Main 中抛出的异常,而无需更改调用链中的每个函数以使用async、await,并返回一个Task?
在我的实际代码中,这个异步函数是从一个非常深的函数调用链中调用的,所有这些函数都应该同步执行。当它们永远不会被异步使用(也不能安全地使用)时让它们全部异步似乎是一个糟糕的主意,如果可能的话,我想避免它。
【问题讨论】:
-
您可以安装自定义同步上下文,因为错误将被发布到它。我认为 Nito Async 有一个。
-
@usr 这不会让异常被“由 Main 中的 catch 块处理”。
-
@i3arnon 同步上下文可以等到异步 void 方法完成。然后将出现异常。 async void 方法甚至不使用同步上下文中的“未完成操作”计数器吗?没有把握。更新:是的,他们有。
-
@usr 它将存在,但它不能真正传播到
main,因为它以同步方法运行。要掌握异常并对其进行处理,您只需在任务上注册一个延续。 -
您愿意进行哪些修改?你愿意修改 Main 吗?修改 DoWork?
void DoWork() { Exec().Wait(); }会为你工作吗?
标签: c# asynchronous async-await