gpt4 book ai didi

c# - 如何将从异步函数抛出的异常传播到等待的 async void 函数?

转载 作者:行者123 更新时间:2023-11-30 20:21:16 32 4
gpt4 key购买 nike

我有一长串调用,最终调用另一个程序集中的异步函数。我希望此函数同步执行,它可能抛出一个异常,我想将其传播到调用链中。

以下代码片段最低限度地重现了此场景:

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 抛出的异常由 Main 中的 catch block 处理,而无需更改调用链中的每个函数以使用 asyncawait,并返回一个Task?

在我的实际代码中,这个异步函数是从一个非常深的函数调用链中调用的,所有这些函数调用都应该同步执行。在永远不会使用它们(也不能安全地使用它们)时将它们全部异步异步似乎是一个糟糕的主意,如果可能的话我想避免它。

最佳答案

This code will cause a crash, because the exception thrown from Exc doesn't get propagated back to DoWork.

完全没有。来自 Exc 的异常被传递给 DoWork 并且如果你有一个 try/catch 可以在那里被捕获做工作

您看到崩溃的原因是 DoWork 正在传播该异常,而 DoWork 是一个 async void 方法。这可以通过将 DoWork 改为 async Task 方法来轻松避免(请注意 async void 应该使用对于事件处理程序,DoWork 显然不是)。正如我在关于最佳实践的 MSDN 文章中所描述的那样,力争 avoid async void .

In my actual code, this asynchronous function is called from a very deep chain of function calls, all of which should executed synchronously. Making them all asynchronous when they'll never be used (nor can they be safely used) asynchronously seems like a terrible idea, and I'd like to avoid it, if possible.

操作要么是异步的,要么不是。由于您调用的低级 API 是异步的,因此您的代码最好异步使用它。尝试将异步代码包装在同步代码中非常容易出错,而且是一个糟糕的主意。尽管有时这是必要的。

因此,最干净的解决方案是让异步方法具有异步签名。是的,这意味着转到“async all the way”,正如我在关于异步最佳实践的 MSDN 文章中所描述的那样。但是,如果您更喜欢异步同步,那么您可以选择 variety of hacks that I describe in my recent "Brownfield async" article 中的一个。 .

关于c# - 如何将从异步函数抛出的异常传播到等待的 async void 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34298664/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com