2009-08-21 8 views
0

Hier ist der Code in Frage:PLINQ Problem/Techniken multi-threaded, schleusenfreien Listen (in C#) impliment

   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); 
       }); 

      }); 

On Laufzeit, dass Code gelegentlich null Referenzen in levelNodes verlässt. Ich vermute, dass dies auf Thread-Sperre zurückzuführen ist, da das Problem verschwindet, wenn ein normales (nicht paralleles) ForEach anstelle von ForAll aufgerufen wird.

Mit der PLINQ-Implementierung, 'levelNodes.Add (Kind);' wirft gelegentlich auch eine IndexOutOfRangeException mit der Meldung: "Quell-Array war nicht lang genug. Überprüfen Sie srcIndex und Länge und die unteren Grenzen des Arrays."

Irgendwelche Vorschläge, um dieses Problem zu beseitigen?
Oder vielleicht würde die Leistung mit einer Lock-Free-List-Implementierung erhöht werden? (Wie könnte man darüber gehen?)

Antwort

4

Brauchen Sie wirklich beide Ebenen der Parallelität hier? Reicht es nicht, nur über die Elternknoten zu parallelisieren?

Wie auch immer, Schreiben auf eine List<T> aus mehreren Threads ohne Verriegelung, wenn definitiv keine gute Idee. PFX wird jedoch mit einer gleichzeitigen Sammlung geliefert, die Ihren Anforderungen entspricht: ConcurrentBag. Es ist ungeordnet (damit es frei von Sperren ist), aber angesichts des Zusammenspiels der Threads hier ist das kein Problem für dich.

+0

Ja, ich bin nur mit der Elternknotenparallelität betroffen. (Die innere Schleife ist nur sequentiell). Danke für die ConcurrentBag-Referenz; das scheint meinen Bedürfnissen zu entsprechen. –