gpt4 book ai didi

c# - 等待异步任务而不在 AggregateException 中包装异常

转载 作者:IT王子 更新时间:2023-10-29 04:42:25 29 4
gpt4 key购买 nike

我正在使用一个提供以 ...Async 结尾的方法的库并返回 Task .我将在命令行应用程序 中使用它们。所以我需要经常同步调用它们。

C#当然不允许在Main中调用这些方法方法,因为您不能使用 async Main 上的修饰符方法。假设这是任务:

var task = datastore.Save(data);

我找到了几个解决方案,例如:

Tasks.WaitAll(task);
task.Wait();

但是所有这些都在 AggregateException 中包含抛出的异常, 我不想要那个。我只想说task.Result并且我希望抛出原始异常。

当我使用返回 Task<TResult> 的方法时, task.Result抛出 AggregateException即使没有设置延续任务。为什么会这样?

我也试过,

task.RunSynchronously();

它给出了错误:

RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.

所以我猜这不适用于标记为 async 的方法.

关于在没有异步上下文的控制台应用程序中使用为异步应用程序设计的库的模式的任何想法?

最佳答案

I am going to use these in a command line application. So I need to call them synchronously a lot.

不,你不知道。您可以使用async - await在控制台应用程序中,您只需要在最顶部进行异步到同步的转换。您可以使用 Wait() 来做到这一点:

public static void Main()
{
MainAsync().Wait();
}

public static async Task MainAsync()
{
var datastore = …;
await datastore.SaveAsync();
}

通常,结合 awaitWait()这是一个坏主意(它可能会导致死锁),但这是正确的解决方案。

请注意,如果 SaveAsync()抛出一个异常而你没有捕捉到它,它将被重新抛出为 AggregateException来自 Wait() .但是你可以在 MainAsync() 中将其作为原始异常捕获(因为它不使用 Wait() )。

如果你真的想直接抛出第一个异常,你可以做类似于await的事情。做:task.GetAwaiter().GetResult() .请注意,如果 Task包含多个异常,您只会得到第一个(但同样适用于 await )。

从 C# 7.1 开始,您可以创建 Main方法 async编译器将为您编写转换代码:

public static async Task Main()
{
var datastore = …;
await datastore.SaveAsync();
}

When I use a method returning Task<TResult>, task.Result throws AggregateException even though there are no continuation tasks set. Why is this happening?

这与延续无关。单Task可以表示多个操作,并且每个操作都可以抛出异常。正因为如此,Task方法总是抛出包裹在AggregateException中的异常.

I also have tried task.RunSynchronously()

这没有任何意义。 RunSynchronously()只能用于 Task使用 Task 创建的构造函数。这里不是这种情况,所以你不能使用它。 Task从异步方法返回的 s 总是已经开始。

关于c# - 等待异步任务而不在 AggregateException 中包装异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17667453/

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