2011-01-24 23 views
9

Il codice seguente crea semplicemente un elenco> di numeri casuali e quindi calcola la somma cumulativa di ogni elenco in un ciclo foreach parallelo. Perché ottengo meno delle valutazioni "numLists"? Spesso intorno al 9990. Immagino che abbia qualcosa a che fare con la sicurezza dei thread. Qual è un metodo alternativo? (Sono un principiante di C# quindi spero di usare termini corretti) Grazie.ciclo foreach parallelo - comportamento anomalo

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; 
     } 
    } 
} 

risposta

11

List<T> non è infatti infilare sicuro, in modo cumsupDataP.Add(...) è caduta dati in modo imprevedibile.

Sostituire questa linea con:

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

e andrà tutto bene. Si noti che è ConcurrentBag<T>non ordinata, ma che va bene perché non avete alcun modo di prevedere l'ordine dai fili in ogni caso; p