在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); } });我们如何使上面的本地最终被调用每次迭代?
In C# Parallel.ForEach localFinally gets called for each partition and not for each iteration, how can we make it to get called for each iteration and not for a partition?
In below example, if we run it it just add one item in the results collection even if trades collection, and hence the iteration, has more than 1 item in it.
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); } });How do we make above local finally to get called for each iteration?
最满意答案
来自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); } });From MSDN:
localInit - The function delegate that returns the initial state of the local data for each task.
body - The delegate that is invoked once per iteration.
localFinally - The delegate that performs a final action on the local state of each task.
For each partition,
localInit is called once body is called zero or more times, depending on how many items the partition processes. localFinally is called onceYou need to do your per-item logic in body. If you want to aggregate the results, you should keep a local list for each partition.
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); } });更多推荐
发布评论