2

我想运行异步 4 层嵌套循环并打印所有聚合异常,但没有这样做。 关注 MS 关于如何处理并行库中的异常的帖子

能明白为什么我总是得到随机数,而它应该打印 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());
        }
    }
}

谢谢

4

1 回答 1

6

counter变量不会以线程安全的方式递增。

由于 TPL 循环将并行运行,因此您的计数器变量将从多个线程递增。由于递增整数变量不是原子的,因此您需要使这部分成为线程安全的,例如通过使用锁或Interlocked.Increment

throw new Exception(string.Format("number {0} failed on iteration {1}", 
                                  number4, 
                                  Interlocked.Increment(ref counter)));
于 2013-01-13T14:53:27.760 回答