Im confused with the example at
http://msdn.microsoft.com/en-us/library/dd997393.aspx
Parallel.ForEach<int, long>(nums, // source collection
() => 0, // method to initialize the local variable
(j, loop, subtotal) =>
{
subtotal += nums[j];
return subtotal;
},
(finalResult) => Interlocked.Add(ref total,finalResult) );
I dont know why the last delegate (finalResult) => Interlocked.Add(ref total,finalResult)
requires an Interlock, whereas the previous expression
(j, loop, subtotal) =>
{
subtotal += nums[j];
return subtotal;
},
does not?
Thanks
The
Parallel.For()andParallel.ForEach()methods make use of a Partitioner. It would be very inefficient to execute a loop over 10,000 elements on 10,000 individual Tasks. The partitioner splits the data in segments and ideally theForEach()will execute in 4 Tasks (threads) of 2,500 elements on a 4-core CPU. This sometimes requires some heuristics and you can write your own custom-partitioner.When using the ‘normal’ (simple) overloads of
ForEach()this is fully transparent. But your example uses one of the<TLocal>overloads that surfaces the partitioning.The
subtotal += nums[j];statement is iterated inside 1 partition and is therefore thread-safe.And
(finalResult) => Interlocked.Add(ref total,finalResult)is where the partitions are merged, this part is of course not thread-safe.