Dela via


Thread-Safe samlingar

.NET Framework 4 introducerar namnområdet, som innehåller flera samlingsklasser System.Collections.Concurrent som är både trådsäkra och skalbara. Flera trådar kan på ett säkert och effektivt sätt lägga till eller ta bort objekt från dessa samlingar, utan att ytterligare synkronisering krävs i användarkoden. När du skriver ny kod använder du de samtidiga samlingsklasserna när flera trådar skrivs till samlingen samtidigt. Om du bara läser från en delad samling kan du använda klasserna i System.Collections.Generic namnområdet. Vi rekommenderar att du inte använder 1.0-samlingsklasser såvida du inte måste rikta in dig på .NET Framework 1.1 eller tidigare körning.

Trådsynkronisering i samlingar .NET Framework 1.0 och 2.0

Samlingarna som introducerades i .NET Framework 1.0 finns i System.Collections namnområdet. Dessa samlingar, som innehåller de vanligaste ArrayList och Hashtable, ger viss trådsäkerhet via Synchronized egenskapen, som returnerar en trådsäker omslutning runt samlingen. Omslutningen fungerar genom att låsa hela samlingen vid varje tilläggs- eller borttagningsåtgärd. Därför måste varje tråd som försöker komma åt samlingen vänta tills dess tur tar ett lås. Detta är inte skalbart och kan orsaka betydande prestandaförsämring för stora samlingar. Dessutom är designen inte helt skyddad från rasförhållanden. Mer information finns i Synkronisering i allmänna samlingar.

Samlingsklasserna som introducerades i .NET Framework 2.0 finns i System.Collections.Generic namnområdet. Dessa inkluderar List<T>, Dictionary<TKey,TValue>och så vidare. Dessa klasser ger bättre typsäkerhet och prestanda jämfört med de .NET Framework 1,0-klasserna. Samlingsklasserna .NET Framework 2.0 tillhandahåller dock ingen trådsynkronisering. Användarkod måste tillhandahålla all synkronisering när objekt läggs till eller tas bort på flera trådar samtidigt.

Vi rekommenderar samtidiga samlingsklasser i .NET Framework 4 eftersom de inte bara ger typsäkerhet för .NET Framework 2.0-samlingsklasser, utan även effektivare och mer fullständig trådsäkerhet än de .NET Framework 1.0-samlingarna tillhandahåller.

Fine-Grained lås- och Lock-Free mekanismer

Vissa av de samtidiga samlingstyperna använder enkla synkroniseringsmekanismer som SpinLock, SpinWait, SemaphoreSlimoch CountdownEvent, som är nya i .NET Framework 4. Dessa synkroniseringstyper använder vanligtvis upptagen spinning under korta perioder innan de försätter tråden i ett sant väntetillstånd. När väntetiderna förväntas bli mycket korta är spinning mycket mindre beräkningsmässigt dyrt än att vänta, vilket innebär en dyr kernelövergång. För samlingsklasser som använder spinning innebär den här effektiviteten att flera trådar kan lägga till och ta bort objekt med mycket hög hastighet. Mer information om spinning kontra blockering finns i SpinLock och SpinWait.

Klasserna ConcurrentQueue<T> och ConcurrentStack<T> använder inte lås alls. I stället förlitar de sig på Interlocked åtgärder för att uppnå trådsäkerhet.

Anteckning

Eftersom de samtidiga samlingsklasserna stöder ICollectiontillhandahåller de implementeringar för IsSynchronized egenskaperna och SyncRoot även om dessa egenskaper är irrelevanta. IsSynchronizedreturnerar false alltid och SyncRoot är alltid null (Nothingi Visual Basic).

I följande tabell visas samlingstyperna System.Collections.Concurrent i namnområdet.

Typ Description
BlockingCollection<T> Tillhandahåller avgränsnings- och blockeringsfunktioner för alla typer som implementerar IProducerConsumerCollection<T>. Mer information finns i Översikt över BlockingCollection.
ConcurrentDictionary<TKey,TValue> Trådsäker implementering av en ordlista med nyckel/värde-par.
ConcurrentQueue<T> Trådsäker implementering av en FIFO-kö (först in, först ut).
ConcurrentStack<T> Trådsäker implementering av en LIFO-stack (last-in, first-out).
ConcurrentBag<T> Trådsäker implementering av en osorterad samling element.
IProducerConsumerCollection<T> Gränssnittet som en typ måste implementera för att användas i en BlockingCollection.
Rubrik Beskrivning
Översikt över BlockingCollection Beskriver funktionerna som tillhandahålls av BlockingCollection<T> typen.
Anvisningar: Lägga till och ta bort objekt från en concurrentDictionary Beskriver hur du lägger till och tar bort element från en ConcurrentDictionary<TKey,TValue>
Anvisningar: Lägga till och ta objekt individuellt från en BlockingCollection Beskriver hur du lägger till och hämtar objekt från en blockerande samling utan att använda den skrivskyddade uppräknaren.
Anvisningar: Lägga till avgränsnings- och blockeringsfunktioner i en samling Beskriver hur du använder en samlingsklass som den underliggande lagringsmekanismen för en IProducerConsumerCollection<T> samling.
Anvisningar: Använd ForEach för att ta bort objekt i en BlockingCollection Beskriver hur du använder foreach, (For Each i Visual Basic) för att ta bort alla objekt i en blockerande samling.
Anvisningar: Använda matriser med blockeringssamlingar i en pipeline Beskriver hur du använder flera blockeringssamlingar samtidigt för att implementera en pipeline.
Anvisningar: Skapa en objektpool med hjälp av en ConcurrentBag Visar hur du använder en samtidig påse för att förbättra prestanda i scenarier där du kan återanvända objekt i stället för att kontinuerligt skapa nya.

Referens

System.Collections.Concurrent