Break parallel.foreach?

62,554

Solution 1

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

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

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

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

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.

Share:
62,554
Rasmus Søborg
Author by

Rasmus Søborg

Worked profesionally for 3+ years on various projects. Potential employee's can PM me, if they are interested in hire. Worked on various projects both large scale and small scale in technologies including but not limited to React &amp; Angular.

Updated on June 09, 2020

Comments

  • Rasmus Søborg
    Rasmus Søborg almost 4 years

    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

  • Mare Infinitus
    Mare Infinitus over 11 years
    exactly. was about to post this myself.
  • Mike Perrenoud
    Mike Perrenoud over 11 years
    +1, it looks like a few of us here have the exact same answer :) -- oh and I got your back up there on that other comment man.
  • Hendrik Wiese
    Hendrik Wiese about 11 years
    Thinking of a sequential foreach loop it's guaranteed that the items before the item that for whatever reason caused the break are processed. What about a Parallel.ForEach where order of the items does not necessarily have to be the order in which they are processed? Is it guaranteed as well that all items in an IEnumerable<...> before the one that invokes state.Break() are being processed and those coming after it are not? Although the former could be achieved somehow, I don't see how the latter would be possible at all.
  • CeejeeB
    CeejeeB about 11 years
    Thanks for this explanation. Do you know when either break or stop are called, is it the case that the currently executing iterations are completed or does it stop the iterations mid way through execution?
  • Reed Copsey
    Reed Copsey almost 11 years
    @CeejeeB Currently executing operations complete.
  • Tudor
    Tudor almost 10 years
    @Hendrik Wiese: Docs say: Calling the Break method informs the for operation that iterations after the current one don't have to execute. However, all iterations before the current one will still have to be executed if they haven't already. and there is no guarantee that iterations after the current one will definitely not execute.
  • xtreampb
    xtreampb over 7 years
    so then would state.Stop() be more appropriate to reliably achieve the expected results, as mentioned below by Mike Perrenoud and MBentley
  • Kellen Stuart
    Kellen Stuart over 3 years
    Is there a more intuitive variable name than state?