Параллельный.ForEach с добавлением в список
Я пытаюсь запустить несколько функций, которые подключаются к удаленному сайту (сети) и вернуть общий список. Но я хочу запустить их одновременно.
например:
public static List<SearchResult> Search(string title)
{
//Initialize a new temp list to hold all search results
List<SearchResult> results = new List<SearchResult>();
//Loop all providers simultaneously
Parallel.ForEach(Providers, currentProvider =>
{
List<SearchResult> tmpResults = currentProvider.SearchTitle((title));
//Add results from current provider
results.AddRange(tmpResults);
});
//Return all combined results
return results;
}
Как я вижу, несколько вставок в "результаты" могут произойти одновременно... Что может привести к краху моего приложения.
Как я могу избежать этого?
5 ответов:
//In the class scope: Object lockMe = new Object(); //In the function lock (lockMe) { results.AddRange(tmpResults); }в основном блокировка означает, что только один поток может иметь доступ к критической секции одновременно.
можно использовать параллельные коллекции.
The
System.Collections.Concurrentпространство имен предоставляет несколько потокобезопасных классов коллекции, которые должны использоваться вместо соответствующих типов вSystem.CollectionsиSystem.Collections.Genericпространства имен, когда несколько потоков одновременно обращаются к коллекции.вы могли бы, например, использовать
ConcurrentBagпоскольку у вас нет гарантии, какой заказ будет добавлен.представляет потокобезопасную, неупорядоченную коллекцию объектов.
параллельные коллекции являются новыми для .Net 4; они предназначены для работы с новой параллельной функциональностью.
посмотреть параллельные коллекции в .NET Framework 4:
перед .NET 4 вам нужно было предоставить свои собственные механизмы синхронизации, если несколько потоков могут обращаться к одной общей коллекции. Ты должен был запереть коллекцию ...
... [новые] классы и интерфейсы в системе.Коллекции.Параллельный [добавлено в .NET 4] обеспечить последовательную реализацию для [...] многопоточные проблемы программирования, связанные с общими данными между потоками.