打破parallel.foreach?


111

如何突破parallel.for循环?

我有一个非常复杂的语句,如下所示:

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

使用并行类,到目前为止,我可以优化此过程。然而; 我不知道如何打破并行循环?该break;语句引发以下语法错误:

没有封闭循环可以中断或继续


1
您是否希望循环的所有并行实例同时中断?
n8wrl 2012年

Answers:


185

使用ParallelLoopState.Break方法:

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

或您的情况:

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

究竟。正要自己张贴这个。
无限母马

1
考虑到顺序的foreach循环,可以确保处理由于某种原因导致中断的项目之前的项目。那么对于Parallel.ForEach来说,项目的顺序不必一定是它们的处理顺序?是否可以保证在IEnumerable <...>中调用state.Break()的所有项目都已处理,而在其后的所有项目均未处理?尽管前者可以通过某种方式实现,但我完全不知道后者将如何实现。
亨德里克·威斯

4
@Hendrik维泽:文件说: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.there is no guarantee that iterations after the current one will definitely not execute.
都铎

2
因此,这样state.Stop()才能更可靠地达到预期的结果,如Mike Perrenoud和MBentley所述(xtreampb,2016
21)

44

为此,您可以使用Parallel.For或的重载(Parallel.ForEach通过循环状态传递)进行调用,然后调用ParallelLoopState.BreakParallelLoopState.Stop。主要区别在于中断的速度-用Break(),循环将处理所有具有比当前“索引”更早的项目。使用Stop(),它将尽快退出。

有关详细信息,请参见如何:从Parallel.For循环停止或中断


3
+1,看来我们这里的一些人有完全相同的答案:)-哦,我支持另一个评论员。
Mike Perrenoud 2012年

感谢您的解释。您是否知道何时调用break或stop,是当前执行的迭代完成还是在执行过程中停止迭代?
CeejeeB

1
@CeejeeB当前执行的操作已完成。
Reed Copsey

12

您应该使用Any而不是foreach循环:

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

Any 只要知道结果必须为真,就足以停止。


10

LoopState当然是一个很好的答案。我发现以前的答案还有很多其他东西,很难看清答案,所以这是一个简单的情况:

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

5

只需使用loopState可以提供的即可。

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

查看此MSDN文章中的示例。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.