Parallèle. Pour chaque exécution ordonnée
Je suis en train d'exécuter des fonctions parallèles sur une liste d'objets à l'aide de la nouvelle C# 4.0 Parallel.ForEach
fonction. C'est un très long processus de maintenance. Je voudrais faire exécuter dans l'ordre de la liste, de sorte que je peux arrêter et de continuer l'exécution dans le point précédent. Comment dois-je faire?
Ici est un exemple. J'ai une liste d'objets: a1 to a100
. C'est l'ordre actuel:
a1, a51, a2, a52, a3, a53...
Je veux cet ordre:
a1, a2, a3, a4...
Je suis OK avec certains objets en cours d'exécution hors de l'ordre, mais aussi longtemps que je peux trouver un point dans la liste où je peux dire que tous les objets avant de ce point, ont été exécutés. J'ai lu la programmation parallèle csharp livre blanc et n'ai rien vu à ce sujet. Il n'y a pas un réglage dans le ParallelOptions
classe.
source d'informationauteur Jeff Z
Vous devez vous connecter pour publier un commentaire.
Si vous utilisez
Parallel.Break
pour fermer la boucle, puis vous garantit que tous les indices au-dessous de la valeur retournée ont été exécutées. C'est à peu près aussi proche que vous pouvez obtenir. L'exemple utilise ici Pour mais ForEach est similaire surcharges.Dans une boucle ForEach, une itération de l'index est généré en interne pour chaque élément dans chaque partition. L'exécution a lieu hors de l'ordre, mais après la pause, vous savez que toutes les itérations inférieur
LowestBreakIteration
aura été complété.Prises de "Programmation Parallèle avec Microsoft .NET" http://parallelpatterns.codeplex.com/
Disponible sur MSDN. Voir http://msdn.microsoft.com/en-us/library/ff963552.aspx. La section "sortir de boucles début de" couvre ce scénario.
Voir aussi: http://msdn.microsoft.com/en-us/library/dd460721.aspx
Comme une suggestion, vous pouvez enregistrer l'objet qui ont été exécutés, puis filtrer la liste lorsque vous reprenez exection à exclure les objets qui ont déjà exécuté.
Si cela doit être persistant à travers redémarrage de l'application, vous pouvez stocker l'ID de la déjà exécuté des objets (je suppose ici que les objets ont une certaine identifiant unique).
Pour quiconque à la recherche d'une solution simple, j'ai posté 2 méthodes d'extension (une à l'aide de PLINQ et une à l'aide de
Parallel.ForEach
) dans le cadre d'une réponse à la question suivante:Commandé PLINQ Pourtout
Faire quelque chose comme ceci:
Vous pouvez voir comment quand vous sortir de la boucle for parallèle vous permettra de connaître le dernier élément de la liste à être exécuté, en supposant que vous laissez tous les threads terminer avant la rupture. Je ne suis pas un grand fan de PLINQ ou LINQ. Honnêtement, je ne vois pas comment de l'écriture de LINQ/PLINQ conduit à maintenable code source ou la lisibilité.... En parallèle.Pour une bien meilleure solution.
Pour quelqu'un d'autre qui vient à travers cette question - si vous êtes en boucle sur un tableau ou d'une liste (plutôt qu'une IEnumberable ), vous pouvez utiliser la surcharge de Parallèle.Foreach qui donne l'index de l'élément à maintenir l'ordre original.
vous pouvez également conserver votre code, et effectuer une Liste.Sort() avant de renvoyer une réponse.