2011-01-24 80 views
9

下面的代碼只是創建一個List>隨機數,然後計算並行foreach循環中每個列表的累積和。我爲什麼得不到'numLists'評估?通常在9990左右。我猜這跟線程安全有關。什麼是替代方法? (我是C#初學者,所以希望我使用正確的術語)謝謝。並行foreach循環 - 奇數行爲

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

回答

11

List<T>確實不是線程安全的,所以cumsupDataP.Add(...)是不可預知的方式丟棄數據。

替換該行:

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

,它會所有的工作。請注意,ConcurrentBag<T>無序,但這很好,因爲您有沒有辦法無論如何都會預測線程的順序; p