【问题标题】:Parallel.ForEach and Aggregate exceptionsParallel.ForEach 和聚合异常
【发布时间】:2013-01-14 00:54:16
【问题描述】:

我想运行异步 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());
        }
    }
}

谢谢

【问题讨论】:

    标签: c# task-parallel-library


    【解决方案1】:

    counter 变量没有以线程安全的方式递增。

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

    throw new Exception(string.Format("number {0} failed on iteration {1}", 
                                      number4, 
                                      Interlocked.Increment(ref counter)));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-07
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多