Udostępnij za pośrednictwem


Struktury danych do 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, lekkie mechanizmy synchronizacji i typy do inicjalizacji leniwej. 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 przestrzeni nazw System.Collections.Concurrent zapewniają bezpieczne operacje dodawania i usuwania wątków, unikając blokad tam, gdzie to możliwe, i stosując szczegółowe blokowanie tam, gdzie blokady są konieczne. 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:

Typ Opis
System.Collections.Concurrent.BlockingCollection<T> Zapewnia funkcje blokowania i ograniczania dla kolekcji bezpiecznych wątkowo, które implementują System.Collections.Concurrent.IProducerConsumerCollection<T> element. Wątki producenta są blokowane, gdy nie ma dostępnych miejsc lub gdy kolekcja jest pełna. Wątki konsumenta zostaną zablokowane, 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ównoległa i skalowalna kolejka FIFO.
System.Collections.Concurrent.ConcurrentStack<T> Współbieżny i skalowalny stos LIFO.

Aby uzyskać więcej informacji, zobacz Thread-Safe Kolekcje.

Prymitywy synchronizacji

Prymitywy synchronizacyjne w przestrzeni nazw System.Threading umożliwiają precyzyjne współbieżne działanie i zwiększoną wydajność, unikając kosztownych mechanizmów blokowania obecnych w starszym kodzie wielowątkowym.

W poniższej tabeli wymieniono typy synchronizacji:

Typ Opis
System.Threading.Barrier Umożliwia równoległe wykonywanie algorytmu przez wiele wątków poprzez zapewnienie punktu, w którym każde zadanie może sygnalizować swoje przybycie, a następnie blokować się do momentu, gdy nie przybędzie część lub wszystkie zadania. Aby uzyskać więcej informacji, zobacz Bariera.
System.Threading.CountdownEvent Upraszcza scenariusze rozgałęzienia i łączenia, zapewniając łatwy mechanizm synchronizacyjny. 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 Prymityw blokady wzajemnego wykluczenia, który powoduje, że wątek, który próbuje uzyskać blokadę, czeka w pętli lub wykonuje spin przez pewien czas przed oddaniem swojego 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 leniwego inicjalizowania

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:

Typ Opis
System.Lazy<T> Zapewnia lekkie, bezpieczne wątkowo inicjowanie.
System.Threading.ThreadLocal<T> Zapewnia leniwie inicjowaną wartość dla każdego wątku, gdzie każdy wątek leniwie wywołuje funkcję inicjalizującą.
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 przed uzyskaniem do nich dostępu.

Aby uzyskać więcej informacji, zobacz Lazy Initialization.

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 System.Threading.Tasks.Parallel oraz PLINQ intensywnie wykorzystują 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 także