c# - 并行 foreach 循环 - 奇怪的行为

标签 c# .net parallel-processing

下面的代码简单地创建了一个随机数列表>,然后在并行的 foreach 循环中计算每个列表的累积和。为什么我得到的评价少于“numLists”?通常在 9990 左右。我猜这与线程安全有关。什么是替代方法? (我是 C# 初学者,所以希望我使用的是正确的术语)谢谢。

using System;  
using System.Collections.Generic;  
using System.Threading.Tasks;  

namespace testParallelForeach
{
    class Program
    {
        static void Main(string[] args)
        {

            List<List<double>> bsData = new List<List<double>>();
            List<List<double>> cumsumDataP = new List<List<double>>();
            int numLists = 10000;
            int myLen = 400;
            Random rand = new Random();
            for (int i = 0; i < numLists; i++)
            {
                bsData.Add(new List<double>());
                for (int j = 0; j < myLen; j++)
                {
                    bsData[i].Add(rand.NextDouble());
                }
            }
            Parallel.ForEach(bsData, a => cumsumDataP.Add(CumulativeSumParallel(a)));
            Console.WriteLine("cumsumDataP.Count={0}", cumsumDataP.Count);
            Console.ReadKey();

        }

        public static List<double> CumulativeSumParallel(List<double> singleRetSeries)
        {
            int r = singleRetSeries.Count;
            List<double> cumsumList = new List<double>();

            cumsumList.Add(singleRetSeries[0]);
            for (int i = 1; i < r; i++)
            {
                cumsumList.Add(cumsumList[i - 1] + singleRetSeries[i]);
            }
            return cumsumList;
        }
    }
}

最佳答案

List<T>确实不是线程安全的,所以cumsupDataP.Add(...)正在以不可预知的方式丢弃数据。

将该行替换为:

ConcurrentBag<List<double>> cumsumDataP = new ConcurrentBag<List<double>>();

一切都会好起来的。注意 ConcurrentBag<T>无序的,但这很好,因为无论如何您无法预测线程的顺序;p

关于c# - 并行 foreach 循环 - 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4779165/

相关文章:

c# - PagedList.Mvc 在 MvcHtmlString 上抛出异常

c# - 如何使用 MS 随机指标

c++ - 如何通过循环将 OpenMP 线程拆分为子团队

c - 在多线程程序中访问文件指针时出错

tensorflow - 为什么 GPU 做矩阵乘法的速度比 CPU 快?

c# - 使用委托(delegate)表示法访问通用列表

c# - 向数据库中添加sql语句

C# Rider 如何在代码块中禁用格式/重新格式化?

.net - SQLite 与 Microsoft Access MDB 相比有多快?

c# - 如何对加载到内存中的可执行文件进行 CRC 检查?