Struktury danych dla Programowania równoległego

Platforma .NET udostępnia kilka typów, które są przydatne w programowaniu równoległym, w tym zestaw współbieżnych klas kolekcji, uproszczone typy pierwotne synchronizacji i typy na potrzeby inicjowania z opóźnieniem. Tych typów można używać z dowolnym kodem aplikacji wielowątkowym, w tym biblioteką równoległą zadań i plINQ.

Współbieżne klasy kolekcji

Klasy kolekcji w System.Collections.Concurrent przestrzeni nazw zapewniają bezpieczne wątkowo dodawanie i usuwanie operacji, które unikają blokad wszędzie tam, gdzie jest to możliwe, i używają precyzyjnego blokowania tam, gdzie są niezbędne blokady. Współbieżna klasa kolekcji nie wymaga, aby kod użytkownika podejmił jakiekolwiek blokady podczas uzyskiwania dostępu do elementów. Współbieżne klasy kolekcji mogą znacznie zwiększyć wydajność w przypadku typów, takich jak System.Collections.ArrayList i System.Collections.Generic.List<T> (z blokadą zaimplementowaną przez użytkownika) w scenariuszach, w których wiele wątków dodaje i usuwa elementy z kolekcji.

W poniższej tabeli wymieniono współbieżne klasy kolekcji:

Type Opis
System.Collections.Concurrent.BlockingCollection<T> Zapewnia możliwości blokowania i ograniczenia dla kolekcji bezpiecznych wątkowo, które implementują System.Collections.Concurrent.IProducerConsumerCollection<T>element . Wątki producenta blokują, jeśli nie są dostępne miejsca lub jeśli kolekcja jest pełna. Wątki odbiorcy blokują, jeśli kolekcja jest pusta. Ten typ obsługuje również nieblokowany dostęp przez konsumentów i producentów. BlockingCollection<T> Może służyć jako klasa bazowa lub magazyn zapasowy w celu zapewnienia blokowania i ograniczenia dla dowolnej klasy kolekcji, która obsługuje IEnumerable<T>.
System.Collections.Concurrent.ConcurrentBag<T> Implementacja torby bezpiecznej wątkowo, która zapewnia skalowalne operacje dodawania i pobierania.
System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue> Współbieżny i skalowalny typ słownika.
System.Collections.Concurrent.ConcurrentQueue<T> Równoczesna i skalowalna kolejka FIFO.
System.Collections.Concurrent.ConcurrentStack<T> Współbieżny i skalowalny stos LIFO.

Aby uzyskać więcej informacji, zobacz Kolekcje wątków Sejf.

Synchronizacja elementów pierwotnych

Synchronizacja elementów pierwotnych w System.Threading przestrzeni nazw umożliwia precyzyjne współbieżność i szybszą wydajność, unikając kosztownych mechanizmów blokowania znalezionych w starszym kodzie wielowątkowym.

W poniższej tabeli wymieniono typy synchronizacji:

Type Opis
System.Threading.Barrier Umożliwia równoległe działanie wielu wątków na algorytmie, zapewniając punkt, w którym każde zadanie może sygnalizować jego przybycie, a następnie blokować do momentu, aż do momentu, gdy dojdą do niektórych lub wszystkich zadań. Aby uzyskać więcej informacji, zobacz Bariera.
System.Threading.CountdownEvent Upraszcza scenariusze rozwidlenia i sprzężenia, zapewniając łatwy mechanizm spotkania. Aby uzyskać więcej informacji, zobacz CountdownEvent.
System.Threading.ManualResetEventSlim Element pierwotny synchronizacji podobny do System.Threading.ManualResetEvent. ManualResetEventSlim jest lżejsza, ale może być używana tylko do komunikacji wewnątrzprocesowej.
System.Threading.SemaphoreSlim Typ pierwotny synchronizacji, który ogranicza liczbę wątków, które mogą jednocześnie uzyskiwać dostęp do zasobu lub puli zasobów. Aby uzyskać więcej informacji, zobacz Semaphore i SemaphoreSlim.
System.Threading.SpinLock Pierwotny blokada wzajemnego wykluczenia, który powoduje, że wątek, który próbuje uzyskać blokadę czekać w pętli lub spin, przez pewien czas przed uzyskaniem kwantu. W scenariuszach, w których oczekuje się, że oczekiwanie na blokadę będzie krótkie, SpinLock zapewnia lepszą wydajność niż inne formy blokowania. Aby uzyskać więcej informacji, zobacz SpinLock.
System.Threading.SpinWait Mały, lekki typ, który będzie obracać się przez określony czas i ostatecznie umieścić wątek w stanie oczekiwania, jeśli liczba spinów zostanie przekroczona. Aby uzyskać więcej informacji, zobacz SpinWait.

Aby uzyskać więcej informacji, zobacz:

Klasy inicjowania z opóźnieniem

W przypadku inicjowania z opóźnieniem pamięć obiektu nie jest przydzielana, dopóki nie będzie potrzebna. Inicjowanie z opóźnieniem może zwiększyć wydajność, rozkładając alokacje obiektów równomiernie przez cały okres istnienia programu. Inicjowanie z opóźnieniem dla dowolnego typu niestandardowego można włączyć, opakowując typ Lazy<T>.

W poniższej tabeli wymieniono leniwe typy inicjowania:

Type Opis
System.Lazy<T> Zapewnia lekkie, bezpieczne wątkowo inicjowanie.
System.Threading.ThreadLocal<T> Zapewnia leniwie zainicjowaną wartość dla każdego wątku, z każdą funkcją inicjowania.
System.Threading.LazyInitializer Udostępnia metody statyczne, które pozwalają uniknąć konieczności przydzielenia dedykowanego wystąpienia inicjowania z opóźnieniem. Zamiast tego używają odwołań, aby upewnić się, że obiekty docelowe zostały zainicjowane w miarę uzyskiwania dostępu do nich.

Aby uzyskać więcej informacji, zobacz Lazy Initialization (Inicjowanie z opóźnieniem).

Wyjątki agregacji

Typ System.AggregateException może służyć do przechwytywania wielu wyjątków zgłaszanych współbieżnie w osobnych wątkach i zwracania ich do wątku sprzęgania jako pojedynczego wyjątku. Typy System.Threading.Tasks.Task i i System.Threading.Tasks.Parallel PLINQ są szeroko używane AggregateException w tym celu. Aby uzyskać więcej informacji, zobacz Obsługa wyjątków i Instrukcje: obsługa wyjątków w zapytaniu PLINQ.

Zobacz też