2016-12-17 18 views
2

我在這裏有一個問題。即時嘗試使用Parallel.foreach將我的數據錶轉換爲列表對象。 是這樣的。Parallel.foreach並不處理所有項目

public List<ProductList> GetProductList(DataTable table) 
{ 
    List<ProductList> list = new List<ProductList>(); 
    Parallel.ForEach(table.AsEnumerable(), item => 
    { 

      string sku = item["product_sku"].ToString(); 
      //int skus = Convert.ToInt16(item["product_sku"]); 

      string price = item["product_price"].ToString(); 

      string tweakerID = item["ID"].ToString(); 
      string finalPrice = item["FinalPrice"].ToString(); 
      list.Add(new ProductList() { SKU = sku, Price = price, ID = id, FinalPrice = finalPrice }); 


    }); 





    list.RemoveAll(item => item == null); 

    return list; 
} 

我有超過65000個產品行。 之後。列表中僅添加約63000種產品。 但結果不是固定的數字。例如最後三次,我跑這個代碼我得到了63202,64025,62920。每次都有一個新號碼。

我也不例外。

+0

MadOX對列表不是線程安全的,但我想知道如果在正常的foreach中執行此操作可能只是一個快速(如果不是更快)。每種方式編寫一些代碼和基準以查看哪個更有效。另一種選擇是必須使用鎖。 – Kevin

+0

我其實也是。並行。如果我在1秒或2秒內獲得60k +行。但在正常的情況下。我在100-150秒內得到它。它真的是一個改進 –

回答

5

那是因爲List<T>不安全。試試看:ConcurrentBag<T>

ConcurentBag存在於System.Collections.Concurrent命名空間,其中包含幾個線程安全集合。

處理所有項目,但並非全部都添加到列表中。原因是,當兩個線程嘗試在完全相同的時間添加不同的項目時,列表無法處理它,並且只保存其中的一個。

+0

它的工作。謝謝 。但是我的表現稍慢一些。但它的okey。感謝MadOX –

+1

我要選擇你的答案解決。我必須等待大約10分鐘才能做到這一點 –

+1

由於它在Add方法上創建鎖對象,所以速度較慢,所以有時線程必須等待。 – MadOX