打破平行线 Foreach?

如何打破 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;语句抛出以下语法错误:

No enclosing loops out of which to break or continue

68175 次浏览

您可以通过使用 Parallel.ForParallel.ForEach的重载进行调用(它们以循环状态传递) ,然后调用 ParallelLoopState.BreakParallelLoopState.Stop来完成此操作。主要区别在于断开的速度——使用 Break()时,循环将处理所有比当前“索引”更早的项。有了 Stop(),它将尽快退出。

有关详细信息,请参阅 如何: 停止或从并行中断。用于循环

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

只需使用可以提供的 loopState

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

MSDN 文章为例。

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

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

Any足够聪明,一旦它知道结果必须是真实的,就会立即停止。

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