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 中留下空引用。我怀疑这是由于线程锁定造成的,因为如果调用普通(非并行)ForEach 代替 ForAll,问题就会消失。

使用 PLINQ 实现,'levelNodes.Add(child);' 有时还会抛出 IndexOutOfRangeException 消息:“源数组不够长。检查 srcIndex 和长度,以及数组的下限。”

有什么建议可以消除这个问题吗?
或者使用无锁列表实现可能会提高性能?(怎么可能呢?)

4

1 回答 1

4

你真的需要两个级别的并行性吗?仅在父节点上并行化还不够吗?

无论如何,如果绝对不是一个好主意,那么从多个线程写入List<T>而不锁定。但是,PFX 带有一个可能满足您需求的并发集合:ConcurrentBag. 它是无序的(允许它是无锁的)但考虑到这里线程之间的相互作用,我想这对你来说不是问题。

于 2009-08-21T06:36:34.267 回答