Параллельный цикл foreach - странное поведение
Приведенный ниже код просто создает список> случайных чисел, а затем вычисляет совокупную сумму каждого списка в параллельном цикле 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;
}
}
}
1 ответ
List<T>
это действительно не потокобезопасный, так cumsupDataP.Add(...)
сбрасывает данные непредсказуемым образом.
Замените эту строку на:
ConcurrentBag<List<double>> cumsumDataP = new ConcurrentBag<List<double>>();
и все будет работать. Обратите внимание, что ConcurrentBag<T>
неупорядочен, но это нормально, потому что вы все равно не можете предсказать порядок из потоков;p