我正在尝试抛出并捕获 AggregateException。
我在 C# 上使用异常的次数不多,但我发现的行为有点令人惊讶。
我的代码是:
var numbers = Enumerable.Range(0, 20);
try
{
var parallelResult = numbers.AsParallel()
.Where(i => IsEven(i));
parallelResult.ForAll(e => Console.WriteLine(e));
}
catch (AggregateException e)
{
Console.WriteLine("There was {0} exceptions", e.InnerExceptions.Count());
}
它正在调用函数 IsEven
private static bool IsEven(int i)
{
if (i % 10 == 0)
throw new AggregateException("i");
return i % 2 == 0;
}
这会引发 AggregateException。
我希望代码能够写入 0,20 范围内的每个偶数,并且“有 1 个例外”两次。
我得到的是打印一些数字(它们是 ForAll 的随机原因),然后抛出异常,但没有捕获并且程序停止。
我错过了什么吗?
这实际上有点有趣。我认为问题是你正在使用AggregateException
以意想不到的方式,这会导致 PLINQ 代码内部出现错误。
整个点AggregateException
是将并行过程中可能同时(或几乎同时)发生的多个异常组合在一起。所以AggregateException
预计至少有一个内部异常。但你正在扔new AggregateException("i")
,没有内部异常。 PLINQ 代码尝试检查InnerExceptions
属性,遇到某种错误(可能是NullPointerException
)然后它似乎进入了某种循环。这可以说是 PLINQ 中的一个错误,因为您正在使用有效的构造函数AggregateException
,即使它是一个不寻常的。
正如其他地方指出的那样,抛出ArgumentException
在语义上会更正确。但是你可以通过抛出一个正确构造的来获得你正在寻找的行为AggregateException
,例如通过改变IsEven
函数是这样的:
private static bool IsEven(int i)
{
if (i % 10 == 0){
//This is still weird
//You shouldn't do this. Just throw the ArgumentException.
throw new AggregateException(new ArgumentException("I hate multiples of 10"));
}
return i % 2 == 0;
}
我认为这个故事的寓意是不要扔AggregateException
除非你真的清楚自己在做什么,特别是如果你已经处于平行或Task
某种基于操作的操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)