Подтвердить что ты не робот

Когда ConcurrentBag лучше, чем List?

Я использую Parallel.Foreach для заполнения внешнего ConcurrentBag. Я также попытался использовать общий список, и все работает нормально.

Мне повезло, или я пропустил специальный объем ConcurrentBag?

4b9b3361

Ответ 1

Вам повезло; Parallel.ForEach для заполнения списка не является потокобезопасным, вы в конечном итоге столкнетесь с проблемами.

Согласно MSDN, List<T> не является безопасным по потоку:

Любые члены экземпляра не гарантируют безопасность потоков.

A Список <T> может поддерживать несколько считывателей одновременно, пока коллекция не модифицировано. Перечисление через коллекцию по сути, не является потокобезопасной процедурой. В редком случае, когда перечисление связано с одним или несколькими обращениями на запись, единственным способом обеспечить безопасность потока, чтобы заблокировать сбор в течение всего перечисление. Чтобы обеспечить доступ к коллекции несколькими темы для чтения и письма, вы должны реализовать свои собственные синхронизации.

ConcurrentBag - это то, что вы должны использовать для этого, который является потокобезопасным для нескольких читателей и писателей.

Ответ 2

Если вы используете Parallel.ForEach для заполнения List<T>, и все работает отлично, вам просто повезет. Метод ForEach может и будет запускать ваш код на нескольких потоках, поэтому любая связь вне ForEach должна быть с объектами, которые могут обрабатывать параллельные обновления. List<T> может не ConcurrentBag<T> can.

Ответ 3

ConcurrentBag - правильный ответ, только в .NET 4.0 он очень медленный. Это было исправлено в .NET 4.5. См. http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

Оба ConcurrentStack и ConcurrentQueue также будут работать в вашей ситуации...