122

如何跳出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;语句引发以下语法错误:

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

4

5 回答 5

201

使用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();
        }
    }));
于 2012-09-24T18:56:38.770 回答
51

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

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

于 2012-09-24T18:56:24.927 回答
12

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

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

Any足够聪明,一旦知道结果一定是真的就停下来。

于 2012-09-24T18:58:04.277 回答
12

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.
});
于 2015-07-31T18:13:49.987 回答
5

只需使用loopState可以提供的。

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

查看此MSDN 文章以获取示例。

于 2012-09-24T18:57:49.633 回答