【问题标题】:PLINQ exceptionPLINQ 异常
【发布时间】:2015-09-07 01:54:48
【问题描述】:

我正在使用 PLINQ,代码如下:

static void Main(string[] args)
    {
        var lt = new List<int>() {1,2,3,4,5};
        try
        {
            var nlt = lt.AsParallel().Select(Test).ToList();
        }
        catch (AggregateException e)
        {
            foreach (var ex in e.InnerExceptions)
            {
                Console.WriteLine(ex.Message);
            }
        }

    }

    private static bool Test(int n)
    {
        if (n == 1)
        {
            Thread.Sleep(1000);
        }
        if (n == 3)
        {
            Thread.Sleep(3000);
        }
        if (n == 5)
        {
            Thread.Sleep(5000);
        }
        if (n == 2 || n == 4)
        {
            throw new Exception("New exception");
        }
        Console.WriteLine("element : {0}", n);
        return true;
    }

结果是总是在 5 秒后抛出一个聚合异常(直到最后一个线程完成)。似乎如果某些线程抛出异常,其余线程仍将继续运行。在最后一个线程完成后,框架会聚合所有异常并将它们包装在一个 aggregateException 中。

如果10个线程中有3个抛出异常,它会等待其余7个线程完成并在最后抛出aggreagteException。

然而,当我看到这份文件时: https://msdn.microsoft.com/en-us/library/dd460712(v=vs.110).aspx

抛出异常后查询无法继续。当您的应用程序代码捕获到异常时,PLINQ 已经停止了所有线程上的查询。

我想知道为什么我的代码不这样运行?如果抛出异常后无法继续查询,则元素 1、3、5 将永远不会打印,因为已经抛出异常。

【问题讨论】:

    标签: c# .net plinq aggregateexception


    【解决方案1】:

    来自您提供的链接:

    当允许异常返回加入线程时,查询可能会在引发异常后继续处理某些项目。

    This section 的 albahari 文章更好地解释了正在发生的事情:

    PLINQ 和 Parallel 类都在遇到第一个异常时结束查询或循环执行 - 不处理任何进一步的元素或循环体。但是,在当前周期完成之前,可能会引发更多异常。 AggregateException 中的第一个异常在 InnerException 属性中可见。

    当抛出异常时,将不再处理集合中的值。但是,在抛出异常时,方法 Test(int) 已经为所有 5 个 int 调用了。在这种情况下,PLINQ 将等待这些方法调用(当前循环),并在它们全部完成后,抛出 AggregateException

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多