Я использую Parallel.Foreach для заполнения внешнего ConcurrentBag. Я также попытался использовать общий список, и все работает нормально.
Мне повезло, или я пропустил специальный объем ConcurrentBag?
Ответ 1
Вам повезло; Parallel.ForEach для заполнения списка не является потокобезопасным, вы в конечном итоге столкнетесь с проблемами.
Согласно MSDN, List<T> не является безопасным по потоку:
Любые члены экземпляра не гарантируют безопасность потоков.
A Список <T> может поддерживать несколько считывателей одновременно, пока коллекция не модифицировано. Перечисление через коллекцию по сути, не является потокобезопасной процедурой. В редком случае, когда перечисление связано с одним или несколькими обращениями на запись, единственным способом обеспечить безопасность потока, чтобы заблокировать сбор в течение всего перечисление. Чтобы обеспечить доступ к коллекции несколькими темы для чтения и письма, вы должны реализовать свои собственные синхронизации.
ConcurrentBag - это то, что вы должны использовать для этого, который является потокобезопасным для нескольких читателей и писателей.
Ответ 2
Если вы используете Parallel.ForEach для заполнения List<T>, и все работает отлично, вам просто повезет. Метод ForEach может и будет запускать ваш код на нескольких потоках, поэтому любая связь вне ForEach должна быть с объектами, которые могут обрабатывать параллельные обновления. List<T> может не ConcurrentBag<T> can.