Parallel.ForEach本地最终没有分区

时间:2016-06-09 14:20:51

标签: c# task-parallel-library

在C#Parallel.ForEach为每个分区调用localFinally而不是为每次迭代调用,我们怎样才能让它为每次迭代调用而不是为分区调用?

在下面的示例中,如果我们运行它,它只是在结果集合中添加一个项目,即使交易集合,因此迭代,其中包含多个项目。

 Parallel.ForEach(trades, parallelOptions,
                    // Loop Init
                () =>
                {
                    var result= new Result();
                    return result;
                },
                    // Loop Body
                (trade, loopState, index, result) =>
                {

                    result= new Result();

                    return result;
                },
                    // Loop Completion
                result=>
                {
                    lock (_lockObj)
                    {
                        results.Add(result);
                        Interlocked.Add(ref count, 1);
                    }
                });

我们如何使上面的本地最终被调用每次迭代?

1 个答案:

答案 0 :(得分:1)

来自MSDN

  

localInit - 返回初始状态的函数委托   每项任务的本地数据。

     

body - 每次迭代调用一次的委托。

     

localFinally - 对每项任务的本地状态执行最终操作的委托。

对于每个分区,

  • localInit被调用一次
  • body被调用零次或多次,具体取决于分区处理的项目数。
  • localFinally被调用一次

您需要在body中执行每项逻辑。如果要聚合结果,则应为每个分区保留一个本地列表。

Parallel.ForEach(trades, parallelOptions,
  // Loop Init
  () =>
  {
    // This creates one list per partition
    return new List<Result>(); // Becomes list
  },
  // Loop Body
  (trade, loopState, index, list) =>
  {
    // Only add the results to the local list for this partition
    list.Add(new Result());
    return list;
  },
  // Loop Completion
  list=>
  {
      lock (_lockObj)
      {
          // Merge the local list from each partition into the shared results list
          results.AddRange(list);
          Interlocked.Add(ref count, list.Count);
      }
  });