web-dev-qa-db-fra.com

Casser parallèle.pour chaque?

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

92
Rasmus Søborg

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

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 .

37
Reed Copsey

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.

11
Servy

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

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.

5
Mike Perrenoud