Правильный способ гарантировать безопасность потоков при добавлении в список с использованием библиотеки Parallel - PullRequest
4 голосов
/ 10 января 2012

Я зацикливаюсь на массиве строк подключения и в каждом цикле извлекаю некоторую информацию и добавляю в список. Теперь я хочу использовать библиотеку Parallel, чтобы сделать ее многопоточной, но я не уверен, гарантирует ли библиотека, что запись в список будет поточно-ориентированной, или мне нужно использовать блокировку:

List<SomeType> list = new List<SomeType>();

settings.AsParallel().ForAll(setting => 
{
    list.AddRange(GetSomeArrayofSomeType(setting)); /// DO I NEED TO DO LOCKING HERE???
})

1 Ответ

10 голосов
/ 10 января 2012

Записи в список действительно не безопасны для многопоточных записей.Вам нужно либо использовать lock для синхронизации доступа, либо использовать коллекцию типа ConcurrentQueue, которая предназначена для многопоточного доступа.

Пример блокировки (при условии, что list является локальным для метода)

List<SomeType> list = new List<SomeType>();
settings.AsParallel().ForAll(setting => { 
  lock (list) {
    list.AddRange(GetSomeArrayofSomeType(setting)); 
  }
});

Или еще лучше использовать SelectMany вместо ForEach

var list = settings
  .AsParallel()
  .SelectMany(setting => GetSomeArrayOfSomeType(setting))
  .ToList();
...