2016-12-17 4 views
2

У меня проблема здесь. im пытается использовать Parallel.foreach для преобразования моего datatable в объект списка. вот так.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

Я действительно сделал. и параллельно. Прежде чем я получил 60k + строк за 1 или 2 секунды. но в обычном foreach. я получаю его через 100-150 секунд. его действительно улучшение –

ответ

5

Thats потому, что List<T> не является безопасным. Попробуйте следующее: ConcurrentBag<T>.

ConcurentBag существует в System.Collections.Concurrent пространства имен, которое содержит еще несколько коллекций, содержащих потоки.

Все элементы обработаны, но не все они добавлены в список. Причина в том, что, когда два потока пытаются добавить разные элементы в одно и то же время, список не может справиться с ним и сохраняет только один из них.

+0

Это работает. Благодарю . но я получаю немного более медленную производительность. но его окей. спасибо MadOX –

+1

Я собираюсь выбрать ваш ответ как решенный. я должен подождать около 10 минут, чтобы сделать это –

+1

Это медленнее, поскольку он создает объект блокировки в методе Add, поэтому иногда потоки должны ждать. – MadOX

Смежные вопросы