Kolekce se zabezpečenými vlákny
.NET Framework 4 zavádí System.Collections.Concurrent obor názvů, který zahrnuje několik tříd kolekcí, které jsou bezpečné pro přístup z více vláken i škálovatelné. Více vláken může bezpečně a efektivně přidávat nebo odebírat položky z těchto kolekcí bez nutnosti další synchronizace v uživatelském kódu. Při psaní nového kódu použijte souběžné třídy kolekce vždy, když se do kolekce současně zapíše více vláken. Pokud čtete jenom ze sdílené kolekce, můžete použít třídy v System.Collections.Generic oboru názvů. Doporučujeme nepoužívat třídy kolekce 1.0, pokud není nutné cílit na modul runtime .NET Framework 1.1 nebo starší.
Synchronizace vláken v kolekcích .NET Framework 1.0 a 2.0
Kolekce představené v .NET Framework 1.0 se nacházejí v System.Collections oboru názvů. Tyto kolekce, které zahrnují běžně používané ArrayList a Hashtableposkytují určité zabezpečení vláken prostřednictvím Synchronized
vlastnosti, která vrací obálku s bezpečným vláknem kolem kolekce. Obálka funguje tak, že při každé operaci přidání nebo odebrání uzamkne celou kolekci. Proto každé vlákno, které se pokouší o přístup k kolekci, musí počkat, až se změní na jeden zámek. To není škálovatelné a může způsobit významné snížení výkonu u velkých kolekcí. Také návrh není zcela chráněn před podmínkami časování. Další informace naleznete v tématu Synchronizace v obecných kolekcích.
Třídy kolekce zavedené v .NET Framework 2.0 jsou nalezeny System.Collections.Generic v oboru názvů. Patří mezi List<T>ně , Dictionary<TKey,TValue>a tak dále. Tyto třídy poskytují lepší bezpečnost a výkon typů v porovnání s třídami .NET Framework 1.0. Třídy kolekce .NET Framework 2.0 však neposkytují žádnou synchronizaci vláken; uživatelský kód musí poskytovat veškerou synchronizaci, pokud jsou položky přidány nebo odebrány na více vláknech současně.
Doporučujeme souběžné třídy kolekcí v .NET Framework 4, protože poskytují nejen bezpečnost typů tříd kolekcí .NET Framework 2.0, ale také efektivnější a ucelenější bezpečnost vláken než .NET Framework 1.0 kolekce poskytují.
mechanismy uzamčení a Lock-Free Fine-Grained
Některé souběžné typy kolekcí používají zjednodušené synchronizační mechanismy, jako SpinLockjsou , SpinWaita CountdownEventSemaphoreSlim, které jsou v .NET Framework 4 nové. Tyto typy synchronizace obvykle používají zaneprázdněné otáčení po krátkou dobu před vložením vlákna do skutečného stavu čekání. Pokud se očekává, že doba čekání bude velmi krátká, je rotace mnohem méně náročná než čekání, což zahrnuje nákladný přechod jádra. U tříd kolekcí, které používají otáčení, tato efektivita znamená, že více vláken může přidávat a odebírat položky velmi vysokou rychlostí. Další informace o otáčení vs. blokování naleznete v tématu SpinLock a SpinWait.
ConcurrentStack<T> Třídy ConcurrentQueue<T> nepoužívají zámky vůbec. Místo toho spoléhají na Interlocked provoz, aby dosáhli bezpečnosti vláken.
Poznámka
Vzhledem k tomu, že souběžné třídy kolekcí podporují ICollection, poskytují implementace pro vlastnosti IsSynchronized , SyncRoot i když tyto vlastnosti nejsou relevantní. IsSynchronized
vždy vrátí false
a SyncRoot
je vždy null
(Nothing
v Visual Basic).
Následující tabulka uvádí typy kolekcí v System.Collections.Concurrent oboru názvů.
Typ | Description |
---|---|
BlockingCollection<T> | Poskytuje ohraničující a blokující funkce pro libovolný typ, který implementuje IProducerConsumerCollection<T>. Další informace naleznete v tématu BlockingCollection Overview. |
ConcurrentDictionary<TKey,TValue> | Implementace slovníku párů klíč-hodnota v bezpečném vlákně |
ConcurrentQueue<T> | Implementace fronty FIFO (first-in, first-out) v bezpečném vlákně |
ConcurrentStack<T> | Implementace zásobníku LIFO (last-in, first-out) bezpečná pro vlákno. |
ConcurrentBag<T> | Implementace neuspořádané kolekce prvků bezpečná pro vlákno. |
IProducerConsumerCollection<T> | Rozhraní, které typ musí implementovat, aby bylo použito v .BlockingCollection |
Související témata
Nadpis | Popis |
---|---|
BlockingCollection – přehled | Popisuje funkce poskytované typem BlockingCollection<T> . |
Postupy: Přidávání a odebírání položek v ConcurrentDictionary | Popisuje, jak přidat a odebrat prvky z objektu ConcurrentDictionary<TKey,TValue> |
Postupy: Přidávání a odebírání jednotlivých položek v BlockingCollection | Popisuje, jak přidat a načíst položky z blokující kolekce bez použití enumerátoru jen pro čtení. |
Postupy: Přidání funkcí ohraničování a blokování do kolekce | Popisuje, jak použít libovolnou třídu kolekce jako základní mechanismus úložiště pro kolekci IProducerConsumerCollection<T> . |
Postupy: Použití příkazu ForEach k odebrání položek v BlockingCollection | Popisuje způsob použití foreach , (For Each v Visual Basic) k odebrání všech položek v blokující kolekci. |
Postupy: Použití polí blokujících kolekcí v datovém kanálu | Popisuje, jak používat více blokujících kolekcí najednou k implementaci kanálu. |
Postupy: Vytvoření fondu objektů pomocí ConcurrentBag | Zobrazuje způsob používání souběžného kontejneru za účelem zlepšení výkonu v situacích, kdy je možné namísto neustálého vytváření nových objektů opětovně používat stávající objekty. |