Использование parallel.foreach с datatable вызывает исключение ссылки на объект

у меня есть этот код в моем проекте. он выполняет некоторую обработку процессора, поэтому для ускорения работы я пытаюсь использовать Parallel.ForEach.

По какой-то причине параллельное выполнение добавляет нулевой элемент, что приводит к исключению «Ссылка на объект не установлена ​​на экземпляр объекта» на более позднем этапе программы.

** Он не должен был добавлять нуль

Рабочий код

foreach (DataRow datarow in dataSet.Tables[0].Rows)
{    
   var item = new T();

   for (int i = 0; i < datarow.Table.Columns.Count; i++)
   {
      var columnName = datarow.Table.Columns[i].ColumnName;
      var columnValue = datarow[i];
      // set new object values
      // use reflection logic to grab values
   }

   finalList.add(item);
}

Код ошибки

List<DataRow> list = dataSet.Tables[0].AsEnumerable().ToList();

Parallel.ForEach<DataRow>(list, datarow =>
{    
   var item = new T();

   for (int i = 0; i < datarow.Table.Columns.Count; i++)
   {
      var columnName = datarow.Table.Columns[i].ColumnName;
      var columnValue = datarow[i];
      // set new object values
      // use reflection logic to grab values
   }

   finalList.add(item);
}

Что это за тип finalList? Если он не может быть изменен одновременно несколькими потоками, вы можете увидеть неожиданное поведение ...

T2PS 10.09.2018 09:20

var list = новый список <T> (); кажется, что все перемешалось

Adam 10.09.2018 09:21

Если finalList не является потокобезопасным, вам необходимо обернуть его блокировкой синхронизации.

JayV 10.09.2018 09:21

так что add () не является потокобезопасным?

Adam 10.09.2018 09:23

мы не знаем, вы еще не сказали, что такое finalList, поэтому мы не можем сказать, является ли он потокобезопасным. если это List<T>, он не безопасен для потоков, что может привести к неожиданному поведению. Где выбрасывается исключение?

René Vogt 10.09.2018 09:24

да, извините, finalList - это нормальный список. Список <T> (). это ошибка.

Adam 10.09.2018 09:30

вместо этого я буду использовать ConcurrentBag

Adam 10.09.2018 09:30

В работающем коде вы перебираете dataSet.Tables[0].Rows, однако в нерабочем коде вы перебираете dataSet.Tables[0].AsEnumerable().ToList(). Вы можете слишком много повторять, потому что во втором примере нет .Rows.

GTHvidsten 10.09.2018 11:04
0
8
374
0

Другие вопросы по теме