Comment sortir d'une boucle parallel.for ?
J'ai une déclaration assez complexe qui ressemble à ce qui suit:
Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
new Action<ColorIndexHolder>((ColorIndexHolder Element) =>
{
if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I)
{
Found = true;
break;
}
}));
En utilisant la classe parallèle, je peux optimiser ce processus de loin. Toutefois; Je n'arrive pas à comprendre comment casser la boucle parallèle? L'instruction break;
Renvoie l'erreur de syntaxe suivante:
Pas de boucles fermantes pour se casser ou continuer
Utilisez le ParallelLoopState.Break
méthode:
Parallel.ForEach(list,
(i, state) =>
{
state.Break();
});
Ou dans votre cas:
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();
}
}));
Vous faites cela en appelant en utilisant la surcharge de Parallel.For
Ou Parallel.ForEach
Qui passe dans un état de boucle, puis en appelant ParallelLoopState.Break
ou ParallelLoopState.Stop
. La principale différence réside dans la rapidité avec laquelle les choses se passent - avec Break()
, la boucle traitera tous les éléments ayant un "index" antérieur à celui en cours. Avec Stop()
, il sortira le plus rapidement possible.
Pour plus de détails, voir Comment: arrêter ou rompre une boucle Parallel.For .
Ce que vous devriez utiliser est Any
, plutôt qu’une boucle foreach:
bool Found = ColorIndex.AsEnumerable().AsParallel()
.Any(Element => Element.StartIndex <= I
&& Element.StartIndex + Element.Length >= I);
Any
est suffisamment intelligent pour s'arrêter dès qu'il sait que le résultat doit être vrai.
LoopState est certainement une excellente réponse. J'ai trouvé que les réponses précédentes contenaient tellement d'autres choses qu'il était difficile de voir la réponse. Voici donc un cas 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.
});
Utilisez simplement le loopState
qui peut être fourni.
Parallel.ForEach<ColorIndexHolder>(ColorIndex.AsEnumerable(),
new Action<ColorIndexHolder>((Element, loopState) => {
if (Element.StartIndex <= I && Element.StartIndex + Element.Length >= I) {
loopState.Stop();
}
}));
Regardez ceci article MSDN pour un exemple.