2011-07-08 12 views
7

Opis ConcurrentBag na MSDN nie jest jasne:Czy Parallel.ForEach w ConcurrentBag <T> bezpieczny wątku

Torby są przydatne do przechowywania przedmiotów podczas zamawiania nie ma znaczenia, w odróżnieniu od zestawów, torby obsługują duplikatów. ConcurrentBag to implementacja worka bezpieczna dla wątków, zoptymalizowana pod kątem scenariuszy, w których ten sam wątek będzie zarówno produkować, jak i konsumować dane przechowywane w torbie.

Moje pytanie jest bezpieczne dla wątków i jeśli jest to dobra praktyka do korzystania z ConcurrentBag w Parallel.ForEach.

Na przykład:

ten sposób nie muszę używać blokowania synchronizacji w Parallel.ForEach stosując regularną listę.

Wielkie dzięki.

Odpowiedz

6

Dla mnie wygląda to dobrze. Sposób, w jaki go używasz, jest bezpieczny dla wątków.

Jeśli możesz zwrócić kod IEnumerable<XYZ>, może on stać się bardziej wydajny, jeśli nie zostanie skopiowany do List<T>, gdy skończysz.

+0

Czy to rzeczywiście poprawia wydajność? Czy funkcja .Add nie zostanie zsynchronizowana, aby była bezpieczna dla wątków? (przy założeniu, że wykreślony kod trwa 0ms). – Sprague

+0

W kolekcjach współbieżnych stosuje się kombinację technik blokowania i blokowania częściowego. Nie blokują całej kolekcji dla każdej operacji. –

+0

Dzięki za wyjaśnienie. Dla zainteresowanych zainicjowałem test porównawczy tego rozwiązania, a także dekompilowałem kod CLR. Używa Interlocked.Exchange i Monitor.Enter. Przypuszczam, że właśnie to nazywasz częściowym blokowaniem? W każdym razie kod równoległy działał szybciej za każdym razem, tylko w przypadku bardzo niskich wartości iteracji i małych opóźnień, sposób "waniliowy" poprawiał wydajność. Nie jestem pewien, czy sam bym użył tej techniki (nie zapominaj, że zakodowany kod musi być bezpieczny dla wątków!), Ale jest szybki. – Sprague

0

ConcurrentBag i Parallel.ForEach wydaje mi się, bez problemu. Jeśli używasz tego typu w scenariuszach, które mają duży dostęp dla wielu użytkowników, te klasy w twojej implementacji mogą podnieść proces procesora do poziomów, które mogą spowodować awarię twojego serwera sieciowego. Ponadto, ta implementacja rozpoczyna N zadań (wątków), aby wykonać każdą z iteracji, więc zachowaj ostrożność przy wyborze tych klas i implementacji. Niedawno spędziłem w tej sytuacji i musiałem wyodrębnić zrzut pamięci, aby przeanalizować, co dzieje się w moim rdzeniu aplikacji sieciowej. Uważaj więc, ponieważ Conurrentbag jest ThreadSafe, a w scenariuszach internetowych nie jest to lepszy sposób.

Powiązane problemy