Как разграничить доступ к списку в 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 шт):
Если не вдаваться в подробности того, что вероятно у вас неверно простроена работа по сети и с БД, то можете попробовать вот такой вариант решения.
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 происходит раньше, чем сам метод завершит работу. Скорее всего, он асинхронный, либо содержит асинхронные вызовы, завершения которых вы не ожидаете, а выполняете возврат из метода.