c# - Break parallel.foreach?
multithreading parallel-processing (5)
¿Cómo salgo de un bucle parallel.for ?
Tengo una declaración bastante compleja que se parece a la siguiente:
Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
new Action<ColorIndexHolder>((ColorIndexHolder Element) =>
{
if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
{
Found = true;
break;
}
}));
Utilizando la clase paralela, puedo optimizar este proceso por mucho. Sin embargo; No puedo entender cómo romper el bucle paralelo? El break;
instrucción arroja el siguiente error de sintaxis:
Sin bucles envolventes para romper o continuar
Lo que debe usar es Any
, en lugar de un bucle foreach:
bool Found = ColorIndex.AsEnumerable().AsParallel()
.Any(Element => Element.StartIndex <= I
&& Element.StartIndex + Element.Length >= I);
Any
es lo suficientemente inteligente como para detenerse tan pronto como sepa que el resultado debe ser cierto.
LoopState es sin duda una gran respuesta. Descubrí que las respuestas anteriores tenían tantas otras cosas que era difícil ver la respuesta, así que aquí hay un caso simple:
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.
});
Para ello, llame utilizando la sobrecarga de Parallel.For
o Parallel.ForEach
que pasa en un estado de bucle, y luego llama a ParallelLoopState.Break
o ParallelLoopState.Stop
. La principal diferencia radica en cuán rápido se rompen las cosas: con Break()
, el ciclo procesará todos los elementos con un "índice" anterior al actual. Con Stop()
, saldrá lo más rápido posible.
Para obtener detalles, consulte Cómo detenerse o interrumpirse desde un paralelo . Para bucle .
Simplemente use el loopState
que se puede proporcionar.
Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
new Action<ColorIndexHolder>((Element, loopState) => {
if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I) {
loopState.Stop();
}
}));
Mira este artículo de MSDN para ver un ejemplo.
Use el método ParallelLoopState.Break
:
Parallel.ForEach(list,
(i, state) =>
{
state.Break();
});
O en tu caso:
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();
}
}));