gpt4 book ai didi

c# - 使用任务并行库Task.WhenAny()时如何处理异常

转载 作者:太空狗 更新时间:2023-10-29 23:06:44 28 4
gpt4 key购买 nike

当我使用 Task.WhenAll() 函数并在任务中抛出异常时,会抛出一个新的 AggregateException,我可以捕获它以查看任务中发生的所有异常。但是,当我使用 Task.WhenAny() 时,不会抛出任何异常。相反,我必须检查 Task.Exception 属性的值以查看是否发生了异常。这似乎是一种不好的代码味道,因为我必须记得在每次使用 Task.WhenAny() 时检查 Task.Exception 属性。难道不应该有更好的方法吗?

这是我的意思的一个例子:

private async void btnMultipleExceptions_Click(object sender, EventArgs e) {
var task1 = ThrowNotImplementedException();
var task2 = ThrowDivideByZeroException();

try {
Task task = await Task.WhenAny(task1, task2);

// Even if an exception is thrown in one of the tasks (in our case,
// task1 will throw first) no exception is thrown from
// the above await Task.WhenAny(). Instead, the exception is placed on the
// Task.Exception property. So I need to check for it every time
// I call Task.WhenAny()?
if (task.Exception != null) {
Console.WriteLine("Exceptions: " + string.Join(Environment.NewLine,
task.Exception.InnerExceptions.Select(x => x.Message).ToArray()));
} else {
Console.WriteLine("No Exceptions!");
}
} catch(Exception ex) {
// Try to catch all exceptions???
AggregateException allEx = ex as AggregateException;

if (allEx != null) {
Console.WriteLine("Exceptions: " + string.Join(Environment.NewLine,
allEx.InnerExceptions.Select(x => x.Message).ToArray()));
} else {
Console.WriteLine("Exceptions: " + ex.Message);
}
}
}

private async Task ThrowNotImplementedException() {
await Task.Delay(TimeSpan.FromSeconds(1));
throw new NotImplementedException();
}

private async Task ThrowDivideByZeroException() {
await Task.Delay(TimeSpan.FromSeconds(2));
throw new DivideByZeroException();
}

最佳答案

简单地等待WhenAny返回的任务。如果它出错了,它会解开异常并抛出它,如果没有,你就知道它已经完成了,所以你可以继续。

或者,您可以简单地在 Task.WhenAny 上调用 Unwrap,然后调用 await。这在语义上与前面的选项相同;唯一的区别在于您是否认为这或多或少很清楚。

如果您发现自己非常频繁地解包 WhenAny 的结果,您可以简单地编写自己的实现来为您解包任务,并改用它们:

public static Task WhenAny(IEnumerable<Task> tasks)
{
return Task.WhenAny(tasks).Unwrap();
}
public static Task<T> WhenAny<T>(IEnumerable<Task<T>> tasks)
{
return Task.WhenAny(tasks).Unwrap();
}
//TODO add wrappers for the `params` overloads if you want them too

关于c# - 使用任务并行库Task.WhenAny()时如何处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30403006/

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