у меня есть этот код в моем проекте. он выполняет некоторую обработку процессора, поэтому для ускорения работы я пытаюсь использовать 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);
}
var list = новый список <T> (); кажется, что все перемешалось
Если finalList
не является потокобезопасным, вам необходимо обернуть его блокировкой синхронизации.
так что add () не является потокобезопасным?
мы не знаем, вы еще не сказали, что такое finalList
, поэтому мы не можем сказать, является ли он потокобезопасным. если это List<T>
, он не безопасен для потоков, что может привести к неожиданному поведению. Где выбрасывается исключение?
да, извините, finalList - это нормальный список. Список <T> (). это ошибка.
вместо этого я буду использовать ConcurrentBag
В работающем коде вы перебираете dataSet.Tables[0].Rows
, однако в нерабочем коде вы перебираете dataSet.Tables[0].AsEnumerable().ToList()
. Вы можете слишком много повторять, потому что во втором примере нет .Rows
.
Что это за тип
finalList
? Если он не может быть изменен одновременно несколькими потоками, вы можете увидеть неожиданное поведение ...