Task Parallel Library provides Parallel.For and
Parallel.Foreach methods to achieve data parallelism. Data parallelism refers to
scenario where you can perform operation in parallel. The Parallel.For and Parallel.foreach
methods are part of System.Threading.Tasks.Parallel.
Sequential loop like below -
for(int i=0; i<10; i++)
Console.Write("{0},",i);
Output -
0,1,2,3,4,5,6,7,8,9,
Parallel for loop –
Parallel.For(0, 10, i => Console.Write("{0},",i));
Output –
2,3,4,8,9,1,7,6,5,0,
Parallel foreach loop -
List<int> numbers = new List<int>() {0, 1, 2, 3, 4, 5, 6,
7, 8, 9 };
Parallel.ForEach(numbers, x => Console.Write("{0},", x));
Output –
2,3,5,7,9,1,8,4,6,0,
As we all know about how sequential loop works. But when
parallel loop executes, the task parallel library partitioned data into multiple
parts and loop can iterate on multiple parts concurrently. Internally task scheduler of TPL partitioned data and distribute data between multiple threads if required. So
you can see the output of parallel for loop is different than sequential for
loop. With parallel loop, order of data is not guaranteed because task parallel
library divides data in multiple parts and process it in parallel.
Parallel For and Foreach loops gives you best performance via utilizing the multiple cores of your machine. Developer can use parallel loops to leverage
full potential of the available hardware. Task parallel Library internally manages
code to adjust with different cores and hardware without changing it. If you
running parallel loops with single core machine this will use single core to
run parallel loops and takes bit more time compare to run the same on four core
machine. See below image where parallel loop utilizes four cores of your machine equally to
complete its operation.
How to break parallel loops in between?
We normally break sequential loops using break keyword like
below.
for (int i = 0; i < 500; i++)
{
if (i == 100)
break;
Console.Write("{0},", i);
}
But you can’t use break with Parallel loops. There is
different way to break parallel loop on some condition. If you want to break
parallel loop, then you need to use different overload
methods of Parallel for and foreach where delegate accepts ParallelLoopState
like below.
public static ParallelLoopResult For(int fromInclusive, int toExclusive, Action<int, ParallelLoopState> body);
See below example to break parallel loops -
Parallel.For(0, 10, (int i, ParallelLoopState loopstate) =>
{
if (i == 5)
{
loopstate.Break();
return;
}
Console.Write("{0},", i);
});
Output –
8,4,2,6,3,0,1,
As you can see in output when variable ‘i’ value is 5, loop
will break. But in parallel loops the order is not guaranteed because task parallel library divides data in multiple parts and run concurrently.
If you break loop in between means loop is not completed
fully. You can check status whether loop is completed or not using ParallelLoopResult.
ParallelLoopResult is return type for almost all Paralle.For and
Parallel.Foreach overload methods. ParallelLoopResult can also be used to know the
value of LowestBreakIteration (loop break value). See below example to check whether
loop is completed or not or break in between.
ParallelLoopResult result = Parallel.For(0, 10,(int i, ParallelLoopState loopstate) =>
{
if (i == 5)
{
loopstate.Break();
return;
}
Console.Write(string.Format("{0},", i));
});
if (result.IsCompleted)
Console.WriteLine("Loop fully
completed.");
else if
(result.LowestBreakIteration.HasValue)
Console.WriteLine("Loop not fully
completed. Broken at value {0}", result.LowestBreakIteration.Value);
Output –
2,3,4,6,1,8,0,
Loop not fully completed. Broken at value 5
I hope this article helps you to know more about
Parallel.For and Paralle.Foreach methods of Parallel extension of Task Parallel
Library. Please leave your feedback in comments below.
Reference –
See also –