2009-08-21 6 views
0

Voici le code en question:PLINQ problème/techniques pour impliment multi-thread, listes sans blocage (en C#)

   parentNodes.AsParallel().ForAll(parent => 
      { 
       List<Piece> plist = parent.Field.GetValidOrientations(pieceQueue[parent.Level]); 

       plist.ForEach(p => 
       { 
        TreeNode child = new TreeNode(p, parent); 
        var score = child.CalculateScore(root); 
        levelNodes.Add(child); 
       }); 

      }); 

Le temps d'exécution, ce code parfois laisse des références nulles dans levelNodes. Je soupçonne que cela est dû au verrouillage du thread, car le problème disparaît si un ForEach normal (non parallèle) est appelé à la place de ForAll.

Avec l'implmentation PLINQ, 'levelNodes.Add (enfant);' lance aussi occasionnellement une exception IndexOutOfRangeException avec le message: "Le tableau source n'a pas été assez long.Vérifiez srcIndex et la longueur, et les limites inférieures du tableau."

Des suggestions pour éliminer ce problème?
Ou peut-être les performances seraient-elles augmentées avec une implimation List sans verrou? (Comment peut-on s'y prendre?)

Répondre

4

Avez-vous vraiment besoin des deux niveaux de parallélisme ici? Ne suffit-il pas de simplement paralléliser sur les nœuds parents?

Quoi qu'il en soit, écrire à un List<T> à partir de plusieurs threads sans verrouillage si certainement pas une bonne idée. Toutefois, PFX est livré avec une collection simultanée qui peut répondre à vos besoins: ConcurrentBag. Ce n'est pas ordonné (pour permettre qu'il soit sans verrou) mais vu l'interaction entre les threads ici, je suppose que ce n'est pas un problème pour vous.

+0

Oui, je ne suis concerné que par le parallélisme des nœuds parents. (La boucle interne est juste séquentielle). Merci pour la référence ConcurrentBag; cela semble convenir à mes besoins. –