Delen via


Thread-Safe verzamelingen

De .NET Framework 4 introduceert de System.Collections.Concurrent naamruimte, die verschillende verzamelingsklassen bevat die zowel thread-veilig als schaalbaar zijn. Meerdere threads kunnen items veilig en efficiënt toevoegen aan of verwijderen uit deze verzamelingen, zonder dat extra synchronisatie in gebruikerscode is vereist. Wanneer u nieuwe code schrijft, gebruikt u de gelijktijdige verzamelingsklassen wanneer meerdere threads gelijktijdig naar de verzameling schrijven. Als u alleen leest vanuit een gedeelde verzameling, kunt u de klassen in de System.Collections.Generic naamruimte gebruiken. U wordt aangeraden geen 1.0-verzamelingsklassen te gebruiken, tenzij u zich moet richten op de .NET Framework 1.1 of eerdere runtime.

Threadsynchronisatie in de verzamelingen .NET Framework 1.0 en 2.0

De verzamelingen die zijn geïntroduceerd in de .NET Framework 1.0, zijn te vinden in de System.Collections naamruimte. Deze verzamelingen, waaronder de veelgebruikte ArrayList en Hashtable, bieden een thread-veiligheid via de Synchronized eigenschap, die een thread-veilige wrapper rond de verzameling retourneert. De wrapper werkt door de hele verzameling te vergrendelen bij elke bewerking voor toevoegen of verwijderen. Daarom moet elke thread die toegang probeert te krijgen tot de verzameling, wachten totdat de verzameling is vergrendeld. Dit is niet schaalbaar en kan leiden tot aanzienlijke prestatievermindering voor grote verzamelingen. Ook is het ontwerp niet volledig beschermd tegen raceomstandigheden. Zie Synchronisatie in algemene verzamelingen voor meer informatie.

De verzamelingsklassen die zijn geïntroduceerd in de .NET Framework 2.0, vindt u in de System.Collections.Generic naamruimte. Deze omvatten List<T>, Dictionary<TKey,TValue>enzovoort. Deze klassen bieden verbeterde typeveiligheid en prestaties in vergelijking met de .NET Framework 1.0-klassen. De .NET Framework 2.0-verzamelingsklassen bieden echter geen threadsynchronisatie; gebruikerscode moet alle synchronisatie bieden wanneer items gelijktijdig worden toegevoegd of verwijderd op meerdere threads.

We raden de gelijktijdige verzamelingsklassen in de .NET Framework 4 aan, omdat ze niet alleen de typeveiligheid bieden van de .NET Framework 2.0-verzamelingsklassen, maar ook efficiëntere en volledigere threadveiligheid bieden dan de .NET Framework 1.0-verzamelingen bieden.

mechanismen voor Fine-Grained vergrendelen en Lock-Free

Sommige van de gelijktijdige verzamelingstypen maken gebruik van lichtgewicht synchronisatiemechanismen zoals SpinLock, SpinWaitSemaphoreSlimen CountdownEvent, die nieuw zijn in de .NET Framework 4. Deze synchronisatietypen maken meestal gebruik van het draaien van korte perioden voordat ze de thread in een werkelijke wachtstatus plaatsen. Wanneer de wachttijden naar verwachting erg kort zijn, is het draaien veel goedkoper dan wachten, wat een dure kernelovergang omvat. Voor verzamelingsklassen die gebruikmaken van spinnen, betekent deze efficiëntie dat meerdere threads items met een zeer hoge snelheid kunnen toevoegen en verwijderen. Zie SpinLock en SpinWait voor meer informatie over draaien versus blokkeren.

De ConcurrentQueue<T> en ConcurrentStack<T> klassen gebruiken helemaal geen vergrendelingen. In plaats daarvan vertrouwen ze op Interlocked bewerkingen om thread-veiligheid te bereiken.

Notitie

Omdat de klassen gelijktijdige verzamelingen ondersteunen ICollection, bieden ze implementaties voor de IsSynchronized en SyncRoot eigenschappen, ook al zijn deze eigenschappen niet relevant. IsSynchronizedretourneert false altijd en SyncRoot is altijd null (Nothingin Visual Basic).

De volgende tabel bevat de verzamelingstypen in de System.Collections.Concurrent naamruimte.

Type Description
BlockingCollection<T> Biedt begrenzings- en blokkeringsfunctionaliteit voor elk type dat wordt geïmplementeerd IProducerConsumerCollection<T>. Zie BlockingCollection Overview voor meer informatie.
ConcurrentDictionary<TKey,TValue> Thread-veilige implementatie van een woordenlijst met sleutel-waardeparen.
ConcurrentQueue<T> Thread-veilige implementatie van een FIFO-wachtrij (first-in, first-out).
ConcurrentStack<T> Thread-veilige implementatie van een LIFO-stack (last-in, first-out).
ConcurrentBag<T> Thread-veilige implementatie van een niet-geordende verzameling elementen.
IProducerConsumerCollection<T> De interface die een type moet implementeren voor gebruik in een BlockingCollection.
Titel Beschrijving
Overzicht van BlockingCollection Beschrijft de functionaliteit van het BlockingCollection<T> type.
Procedure: Items toevoegen aan en verwijderen uit een Gelijktijdigedictionary Hierin wordt beschreven hoe u elementen toevoegt aan en verwijdert uit een ConcurrentDictionary<TKey,TValue>
Procedure: Items afzonderlijk toevoegen en overnemen vanuit een BlockingCollection Hierin wordt beschreven hoe u items toevoegt aan en ophaalt uit een blokkeringsverzameling zonder de alleen-lezen opsomming te gebruiken.
Procedure: Begrenzings- en blokkeringsfunctionaliteit toevoegen aan een verzameling Beschrijft hoe u een verzamelingsklasse gebruikt als het onderliggende opslagmechanisme voor een IProducerConsumerCollection<T> verzameling.
Procedure: ForEach gebruiken om items in een BlockingCollection te verwijderen Beschrijft hoe foreachu (For Each in Visual Basic) alle items in een blokkeringsverzameling verwijdert.
Procedure: matrices van blokkerende verzamelingen in een pijplijn gebruiken Hierin wordt beschreven hoe u meerdere blokkerende verzamelingen tegelijk gebruikt om een pijplijn te implementeren.
Procedure: Een objectgroep maken met behulp van een ConcurrentBag Laat zien hoe u een gelijktijdige zak gebruikt om de prestaties te verbeteren in scenario's waarin u objecten kunt hergebruiken in plaats van voortdurend nieuwe objecten te maken.

Verwijzing

System.Collections.Concurrent