【问题标题】:PLINQ problem / techniques to impliment multi-threaded, lock-free lists (in C#)PLINQ 问题/实现多线程、无锁列表的技术(在 C# 中)
【发布时间】:2010-11-21 13:45:16
【问题描述】:

这是有问题的代码:

             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 和长度,以及数组的下限。”

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

【问题讨论】:

    标签: c# linq multithreading list plinq


    【解决方案1】:

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

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

    【讨论】:

    • 是的,我只关心父节点的并行性。 (内部循环只是顺序的)。感谢 ConcurrentBag 参考;这似乎符合我的需要。
    猜你喜欢
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-28
    • 1970-01-01
    相关资源
    最近更新 更多