简体   繁体   中英

Break parallel.foreach?

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

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();
        }
    }));

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 .

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.

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.
});

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM