C#并行循环局部变量线程安全信息

Saa*_*adi 7 .net c# asp.net multithreading task-parallel-library

我的问题很少理论我想知道List<object>如果我Parallel.For以这种方式使用是否是线程安全的.请看下面:

public static List<uint> AllPrimesParallelAggregated(uint from, uint to)
        {
            List<uint> result = new List<uint>();
            Parallel.For((int)from, (int)to,
                () => new List<uint>(), // Local state initializer
                (i, pls, local) =>      // Loop body
                {
                    if (IsPrime((uint)i))
                    {
                        local.Add((uint)i);
                    }
                    return local;
                },
                local =>                // Local to global state combiner
                {
                    lock (result)
                    {
                        result.AddRange(local);
                    }
                });
            return result;
        }
Run Code Online (Sandbox Code Playgroud)

local列表是线程安全的?我是否在result没有数据的情况下列表中的正确数据是由于多个线程正在改变,因为使用我正常循环?

注意:我不担心列表顺序.我想知道列表和数据的长度.

Joh*_* Wu 7

这个解决方案是线程安全的吗?技术上是的,实际上没有.

线程安全List(与队列或包相对)的概念是列表对于顺序是安全的,或者更严格地说是索引,因为除了升序整数之外没有其他键.在一个平行的世界中,当你想到它时,它就是一种荒谬的概念.这就是System.Collections.Concurrent命名空间包含a ConcurrentBag和a ConcurrentQueue但不包含的原因ConcurrentList.

由于您询问列表的线程安全性,我假设您的软件要求生成一个按升序排列的列表.如果是这种情况,不,您的解决方案将无效.虽然代码在技术上是线程安全的,但线程可以按任何顺序完成,并且您的变量result最终将不进行排序.

如果您希望使用并行计算,则必须将结果存储在一个包中,然后在所有线程完成后对包进行排序以生成有序列表.否则,您必须连续执行计算.

既然你必须使用一个包,你也可以使用ConcurrentBag,然后你就不必费心了lock{}.