0

問題のコードは次のとおりです。

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

            });

実行時に、そのコードはlevelNodesにnull参照を残すことがあります。ForAllの代わりに通常の(非並列の)ForEachが呼び出されると問題が解消されるため、これはスレッドロックが原因であると思われます。

PLINQの実装では、'levelNodes.Add(child);' また、「ソース配列の長さが十分ではありませんでした。srcIndexと長さ、および配列の下限を確認してください。」というメッセージとともにIndexOutOfRangeExceptionがスローされることもあります。

この問題を解消するための提案はありますか?
それとも、ロックフリーのリストを実装することでパフォーマンスが向上するでしょうか?(これについてはどうすればよいでしょうか?)

4

1 に答える 1

4

ここで両方のレベルの並列処理が本当に必要ですか? 親ノードを並列化するだけでは十分ではありませんか?

とにかく、List<T>絶対に良い考えではない場合、ロックせずに複数のスレッドから a に書き込みます。ただし、PFX には、ニーズに合った同時実行コレクションが付属していますConcurrentBag。(ロックフリーにするため) 順序付けされていませんが、ここでのスレッド間の相互作用を考えると、それは問題ではないと思います。

于 2009-08-21T06:36:34.267 に答える