c# - PLINQ 异常

标签 c# .net 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;
    }

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

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

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

the query cannot continue after the exception is thrown. By the time your application code catches the exception, PLINQ has already stopped the query on all threads.

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

最佳答案

从您提供的链接:

When exceptions are allowed to bubble up back to the joining thread, then it is possible that a query may continue to process some items after the exception is raised.

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

Both PLINQ and the Parallel class end the query or loop execution upon encountering the first exception — by not processing any further elements or loop bodies. More exceptions might be thrown, however, before the current cycle is complete. The first exception in AggregateException is visible in the InnerException property.

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

关于c# - PLINQ 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32430134/

相关文章:

c# - 为什么 NLog ${aspnet-request-host} 是空的?

c# - 分区组的外部配置文件

c# - Plinq 语句在静态构造函数中陷入僵局

c# - 异常显示开发人员的路径而不是服务器

c# - 将 List<List<object>> 转换为 IList<IList<object>>

mysql - 电话号码转换和比较

c# - PLINQ 是否保留序列中的原始顺序?

.net - .NET 4.0和4.5中损坏的PLINQ ForAll

c# - 使用多个 ServicePointManager.SecurityProtocol,它首先尝试什么?

c# - TSqlUnit 值得使用吗?