这是List<>的c#用法吗?线程安全?

时间:2013-07-10 15:52:39

标签: c#

我有C#.Net 4代码,它正在添加到List<>在Parallel.For中。 如果这是线程安全的话,我找不到明确的答案。 如果不安全有什么替代方案?

    static List<int> Calculate(List<string[]> numbers)
    {
           List<int> sums = new List<int>();


            Parallel.ForEach(numbers,
            (nums) =>
            {
                int sum = 0;
                for (int i = 0; i < nums.Length; i++)
                     sum += Convert.ToInt32( nums[i]);

                // is this thread safe or not???
                sums.Add(sum);
            });

            sums.Sort();
            return sums;
    }

3 个答案:

答案 0 :(得分:10)

不,它不是线程安全的。您可能正在寻找ConcurrentBag<T> class,一个线程安全的无序集合。 MSDN's Thread-Safe Collections documentation提供了更多信息和其他线程安全集合。 E.g。

static List<int> Calculate(List<string[]> numbers)
{
       var sums = new ConcurrentBag<int>();


        Parallel.ForEach(numbers,
        (nums) =>
        {
            int sum = 0;
            for (int i = 0; i < nums.Length; i++)
                 sum += Convert.ToInt32( nums[i]);

            sums.Add(sum);
        });

        var sorted = sums.OrderBy(x => x).ToList();
        return sorted;
}

答案 1 :(得分:3)

不,不是。

  

List可以同时支持多个读者,只要   集合未被修改。列举一个集合是   本质上不是一个线程安全的程序。在罕见的情况下   枚举与一个或多个写访问争用,唯一的方法   确保线程安全是在整个过程中锁定集合   列举。允许多个访问集合   阅读和写作的线程,你必须实现自己的   同步。

来自MSDN

答案 2 :(得分:3)

通过将方法转换为PLINQ操作,可以避免线程安全问题(并提高性能):

static List<int> Calculate(List<string[]> numbers)
{
    return numbers.AsParallel()
                  .Select(nums => nums.Sum(Convert.ToInt32))
                  .OrderBy(i => i)
                  .ToList();
}