繁体   English   中英

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

[英]Parallel.Foreach loop, inconsistent behavior with explicit throw statement

使用Linqpad创建了一个简单程序,其中我在Parallel Foreach循环中显式抛出一个异常,理想情况下,该Aggregate Exception应作为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代替

有一个选项定义在这里 ,收集在所有异常ConcurrentQueue它们扔后来由于聚集的例外,但为什么如预期当前代码不工作,我不是很肯定。 在这种情况下,我们期望输出为:

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

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

这完全是预期的行为。

参见文档

未处理的异常导致循环立即终止

引发异常时,不会安排任何新任务。

因此,该行为将显得不可预测。 您无权期望所有子任务都将执行。 那不是Parallel.For循环的约定。

当您向源列表中添加更多项目时,差异将更加明显。 输出将始终在ThreadPool.MinThreads附近显示许多异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM