Break parallel.foreach?

C#MultithreadingParallel Processingparallel.foreach

C# Problem Overview


How do I break out of an parallel.for loop?

I have a pretty complex statement which looks like the following:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder>((ColorIndexHolder Element) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            break;
        }
    }));

Using parallel class, I can optimize this process by far. However; I cannot figure out how to break the parallel loop? The break; statement throws following syntax error:

> No enclosing loops out of which to break or continue

C# Solutions


Solution 1 - C#

Use the ParallelLoopState.Break method:

 Parallel.ForEach(list,
    (i, state) =>
    {
       state.Break();
    });

Or in your case:

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
    new Action<ColorIndexHolder, ParallelLoopState>((ColorIndexHolder Element, ParallelLoopState state) =>
    {
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
        {
            Found = true;
            state.Break();
        }
    }));

Solution 2 - C#

You do this by calling using the overload of Parallel.For or Parallel.ForEach which passes in a loop state, then calling ParallelLoopState.Break or ParallelLoopState.Stop. The main difference is in how quickly things break - with Break(), the loop will process all items with an earlier "index" than the current. With Stop(), it will exit as quickly as possible.

For details, see How to: Stop or Break from a Parallel.For Loop.

Solution 3 - C#

LoopState is certainly a great answer. I found the previous answers had so much other stuff that it was hard to see the answer, so here is a simple case:

using System.Threading.Tasks;

Parallel.ForEach(SomeTable.Rows(), (row, loopState) =>
{
    if (row.Value == testValue)
    {
        loopState.Stop();  // Stop the ForEach!
    }       
    // else do some other stuff here.
});

Solution 4 - C#

What you should be using is Any, rather than a foreach loop:

bool Found = ColorIndex.AsEnumerable().AsParallel()
    .Any(Element => Element.StartIndex <= I 
      && Element.StartIndex + Element.Length >= I);

Any is smart enough to stop as soon as it knows that the result must be true.

Solution 5 - C#

Just use the loopState that can be provided.

Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),  
    new Action<ColorIndexHolder>((Element, loopState) => { 
        if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I) { 
            loopState.Stop();
        }     
})); 

Look at this MSDN article for an example.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRasmus S&#248;borgView Question on Stackoverflow
Solution 1 - C#TudorView Answer on Stackoverflow
Solution 2 - C#Reed CopseyView Answer on Stackoverflow
Solution 3 - C#MBentleyView Answer on Stackoverflow
Solution 4 - C#ServyView Answer on Stackoverflow
Solution 5 - C#Mike PerrenoudView Answer on Stackoverflow