Parallel.Foreach循环,行为与显式throw语句不一致

时间:2018-09-13 08:42:39

标签: c# .net task-parallel-library parallel.foreach aggregateexception

使用Linqpad创建了一个简单程序,其中我在Parallel Foreach循环中显式引发异常,理想情况下,该异常应作为Aggregate Exception捕获在调用方中,但是当我显式引发异常时,它将有时会随机跳过一些例外情况。我无法理解这种行为,任何可以解释的人:

void Main()
{
    try
    {
      var intList = new List<int> {1,2,3,4,5,6};

      Parallel.ForEach(intList, i => Test1(i));
    }
    catch (AggregateException aggregateException)
    {
        foreach (var ex in aggregateException.Flatten().InnerExceptions)
        {
            ex.Message.Dump();
        }
    }
}

public void Test1(int i)
{
    try
    {
        if (i % 2 != 0)
            throw new Exception($"{i} - Odd value exception");

    }
    catch(Exception ex)
    {
        ex.Message.Dump();
        throw;
    }
}

public void Test2(int i)
{
        if (i % 2 != 0)
            throw new Exception($"{i} - Odd value exception");
}

public void Test3(int i)
    {
        try
        {
            if (i % 2 != 0)
                throw new Exception($"{i} - Odd value exception");

        }
        catch(Exception ex)
        {
            ex.Message.Dump();
        }
    }

详细信息:

  1. 有两个版本的Test,一个带有显式的Try Catch,另一个不带
  2. 在Test1中,两者都具有相似的不一致行为,即使本地try catch也不会显示该值
  3. 可以有第三个版本Test3,它们总是可以工作,因为没有明确地将异常排除在并行循环之外
  4. Dump是一个linqpad打印呼叫,在Visual Studio中由Console.WriteLine取代

有一个定义为here的选项,该选项收集ConcurrentQueue中的所有异常并在以后将它们作为聚合异常抛出,但是为什么当前代码不能按预期运行,我不太确定。在这种情况下,我们期望输出为:

1 - Odd value exception
3 - Odd value exception
5 - Odd value exception

但是其中一些随机地被跳过了,在一个简单的程序中,复杂程序中的遗漏也更多了,而它们的工作量则更大

0 个答案:

没有答案