并行 foreach 循环 - 奇怪的行为 [英] parallel foreach loop - odd behavior

查看:30
本文介绍了并行 foreach 循环 - 奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The code below simply creates a List> of random numbers and then calculates the cumulative sum of each list in a parallel foreach loop. Why do I get less than 'numLists' evaluations? Often around 9990. I'm guessing it has something to do with thread safety. What's an alternative method? (I'm a C# beginner so hopefully I'm using correct terms) Thanks.

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 确实不是线程安全的,所以 cumsupDataP.Add(...)正在以不可预测的方式丢弃数据.

List<T> is indeed not thread safe, so cumsupDataP.Add(...) is dropping data in unpredictable ways.

将该行替换为:

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

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

and it will all work. Note that ConcurrentBag<T> is unordered, but that is fine because you have no way of predicting the order from the threads anyway ;p

这篇关于并行 foreach 循环 - 奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆