Обновление вне цикла

У меня есть расположение различных файлов csv в массиве strFilePath (почти 1000 файлов, в каждом из которых содержится 1 миллион записей). Чтение файлов и объединение всех данных в одну таблицу данных занимает много времени. Поэтому я решил продолжить параллельную обработку.

ТЕКУЩИЙ КОД

DataTable dtMerge=new DataTable();
for(int i=0;i<strFilePath.Count;i++)
{
     Parallel.For(0, 3,m =>
     {
         clsNewClass objCls=new clsNewClass();
         DataTable dt=objCls.ReadCSV(strFilePath[m+i]);
     });
     m+=3;
}

Вопрос в том, как я могу объединить все данные из таблицы данных dt в глобальную таблицу данных dtMerge или включить все результаты в глобальную переменную dtMerge?

КОД ОЖИДАЕТСЯ РАБОТАТЬ

DataTable dtMerge=new DataTable();
for(int i=0;i<strFilePath.Count;i++)
{
     Parallel.For(0, 3,m =>
     {
         clsNewClass objCls=new clsNewClass();
         // Is it possible like the below?
         dtMerge = objCls.ReadCSV(strFilePath[m+i]);
     });
     m+=3;
}

person Sarath KS    schedule 14.09.2014    source источник
comment
У вас довольно много ошибок в существующем коде. m не заявлен у m+=3 это первое, что у меня выскакивает. На самом деле вам может быть гораздо лучше сделать Parallel.ForEach(strFilePath, filepath => { ... })   -  person Scott Chamberlain    schedule 03.12.2014
comment
В конце концов, как бы я слил это? Есть ли способ без использования блокировки (объекта) внутри Parallel.Foreach? @Скотт Чемберлен   -  person Sarath KS    schedule 03.12.2014


Ответы (1)


Используйте перегрузку Parallel.For (или ForEach), которая дает вам локальный инициализатор и, наконец, для потоков, чтобы вы могли объединять свой прогресс внутри потока без использования блокировок. Затем вы можете объединить свои таблицы внутри потоков в блоке finally к вашей внешней таблице, используя блокировку для безопасности потоков.

DataTable dtMerge = new DataTable();

Parallel.ForEach(strFilePath,
     () => new DataTable(),
     (filePath, loopState, local) =>
     {
         clsNewClass objCls=new clsNewClass();
         // Is it possible like the below?
         var dt = objCls.ReadCSV(filePath);
         local.Merge(dt, true, MissingSchemaAction.Add);
         return local;
     },
     (local) =>
     {
         lock(dtMerge)
         {
             dtMerge.Merge(local, true, MissingSchemaAction.Add);
         }
     });

Я также избавился от вашего внешнего цикла for и заменил ваш внутренний цикл параллельным foreach, поэтому не было причин вкладывать ваши циклы таким образом, просто используйте ForEach

person Scott Chamberlain    schedule 03.02.2015
comment
Я сомневаюсь. Будет ли эта блокировка действительно отражать производительность Parallel.ForEach? На самом деле lock гарантирует, что только 1 объект может получить доступ одновременно. Верно??? - person Sarath KS; 03.02.2015
comment
Блокировка происходит только тогда, когда рабочий поток удаляется, поэтому это происходит очень редко. local.Merge - это тот, который будет происходить часто и не имеет блокировки (и не нужен, потому что таблица, с которой вы объединяетесь, является локальным объектом потока) - person Scott Chamberlain; 03.02.2015
comment
Большое спасибо за ваше драгоценное время и ответ :) @Scott Chamberlain - person Sarath KS; 03.02.2015