Break Parallel Foreach Earlier
Breaking out of a Parallel.ForEach isn’t as straightforward as a normal foreach, but .NET gives you built-in control methods for it.
1. Use Break()
Stops starting new iterations after a certain point, but lets already-running ones finish.
Parallel.ForEach(collection, (item, state) =>
{
if (SomeCondition(item))
{
state.Break();
return;
}
// Work here
});
When to use:
• When order matters (mainly useful with indexed loops)
• You want to stop future iterations, not cancel everything immediately
2. Use Stop() (most common for “break early”)
Stops all iterations as soon as possible.
Parallel.ForEach(collection, (item, state) =>
{
if (SomeCondition(item))
{
state.Stop();
return;
}
// Work here
});
Behavior:
• Prevents new iterations from starting
• Already-running iterations may still complete
3. Check IsStopped (optional optimization)
Parallel.ForEach(collection, (item, state) =>
{
if (state.IsStopped)
return;
if (SomeCondition(item))
{
state.Stop();
return;
}
// Work
});
4. Using CancellationToken (best for external control)
var cts = new CancellationTokenSource();
try
{
Parallel.ForEach(collection, new ParallelOptions
{
CancellationToken = cts.Token
},
(item, state) =>
{
if (SomeCondition(item))
{
cts.Cancel();
return;
}
// Work
});
}
catch (OperationCanceledException)
{
Console.WriteLine("Cancelled");
}
Important Notes
• There is no instant hard break like in a normal loop
• Parallel loops are cooperative — running tasks must finish or check flags
• Stop() is usually what people want when they say “break early”
One more example
Use the ParallelLoopState.Break or ParallelLoopState.Stop method to end parallel foreach loop:
public void BreakParallelForeachEarlier()
{
var list = new List<Int32>();
for (var i = 0; i < 100; ++i)
list.Add(i);
var startTime = DateTime.Now;
var maxRunTimeInMs = 2500;
Parallel.ForEach(list, (elem, state) =>
{
Console.WriteLine("Running for {0}", elem);
Thread.Sleep(1000 + elem); // Running exhausting algorithm
var duration = (DateTime.Now - startTime).TotalMilliseconds;
if (duration > maxRunTimeInMs)
{
Console.WriteLine("Exiting the parallel foreach block...");
state.Break();
}
});
}