PLINQ 异常
PLINQ exception
我正在使用带有以下代码的 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,因为异常已经抛出。
根据您提供的link:
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.
albahari 文章的 This section 更好地解释了正在发生的事情:
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.
抛出异常时,将不再处理集合中的更多值。但是,在抛出异常时,已经为所有 5 个整数调用了方法 Test(int)
。在这种情况下,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,因为异常已经抛出。
根据您提供的link:
albahari 文章的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 更好地解释了正在发生的事情:
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.
抛出异常时,将不再处理集合中的更多值。但是,在抛出异常时,已经为所有 5 个整数调用了方法 Test(int)
。在这种情况下,PLINQ 将等待这些方法调用(当前周期),并在所有方法调用完成后抛出 AggregateException
.