我想运行异步4层嵌套循环并打印所有聚合异常,但未能这样做。 Followed MS post on how to handle exception in Parallel library
可以得到为什么我总是得到随机数,而它应该打印3 ^ 3次?
Console.WriteLine("{0} was on counter\n\n\n",counter);
class Program
{
static void Main()
{
int counter = 1;
List<int> numbers = new List<int> {1, 2, 3};
try
{
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(numbers, number1 =>
{
Parallel.ForEach(numbers, number2 =>
{
Parallel.ForEach(numbers, number3 =>
{
Parallel.ForEach(numbers, number4 =>
{
try
{
throw new Exception(string.Format("number {0} failed on iteration {1}",number4,counter++));
}
catch (Exception exception)
{
exceptions.Enqueue(exception);
}
});
});
});
});
if (!exceptions.IsEmpty)
{
throw new AggregateException(exceptions);
}
}
catch (Exception exception)
{
Console.WriteLine("{0} was on counter\n\n\n",counter);
GetInnerException(exception);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
public static void GetInnerException(Exception exception)
{
if (exception.GetType().Equals(typeof(AggregateException)))
{
AggregateException aggregateException = (AggregateException)exception;
foreach (Exception innerException in aggregateException.InnerExceptions)
{
GetInnerException(innerException);
}
}
else
{
Console.WriteLine(exception.ToString());
}
}
}
感谢
答案 0 :(得分:6)
counter
变量不以线程安全的方式递增。
由于TPL循环将并行运行,您的计数器变量将从多个线程递增。由于递增整数变量不是原子的,因此您需要将此部分设置为线程安全的,例如使用锁或Interlocked.Increment:
throw new Exception(string.Format("number {0} failed on iteration {1}",
number4,
Interlocked.Increment(ref counter)));