PLINQ例外

Sea*_*ean 3 .net c# plinq aggregateexception

我正在使用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;
    }
Run Code Online (Sandbox Code Playgroud)

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

是框架行为,如果10个线程中有3个抛出异常,它将等待其余7个线程完成并在结束时抛出aggreagteException.

但是,当我遇到这个文档时:https: //msdn.microsoft.com/en-us/library/dd460712(v = vs.110).aspx

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

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

Fer*_*oto 7

从您提供的链接:

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

这部分 albahari的文章更好地解释了发生的事情:

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

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