Как разграничить доступ к списку в Parallels.For

В многопотоке делаю гет-запросы. Результат пихаю в список. Дальше в монопольном режиме хочу запихнуть данные в БД. Почему то lock не даёт монопольный доступ к InsertRowsToDB, так как у меня в БД дублируются данные.

var rows = new List<string>();
Object locker = new Object();
Parallel.For(0,urls.Count, new ParallelOptions { MaxDegreeOfParallelism = 100}, (i) =>
{
   var data = GetRequest(urls[i]);
   lock(locker)
     {
       rows.Add(data);
       
       if (rows.Count>=100)
       {
           InsertRowsToDB(rows); 
           rows.Clear();
       }
     }
});
                  

Ответы (1 шт):

Автор решения: aepot

Если не вдаваться в подробности того, что вероятно у вас неверно простроена работа по сети и с БД, то можете попробовать вот такой вариант решения.

var rows = new List<string>();
Object locker = new Object();
Parallel.For(0,urls.Count, new ParallelOptions { MaxDegreeOfParallelism = 100}, (i) =>
{
   var data = GetRequest(urls[i]);
   lock(locker)
   {
       rows.Add(data);
       
       if (rows.Count>=100)
       {
           InsertRowsToDB(rows); 
           rows = new List<string>();
       }
   }
});
InsertRowsToDB(rows);

В этом случае, список, переданный в метод InsertRowsToDB не будет изменен после передачи.

А происходит это потому что возврат из метода InsertRowsToDB происходит раньше, чем сам метод завершит работу. Скорее всего, он асинхронный, либо содержит асинхронные вызовы, завершения которых вы не ожидаете, а выполняете возврат из метода.

→ Ссылка