Programmering

Sådan arbejder du med BlockingCollection i C #

Overvej et scenarie, hvor flere tråde læser og skriver til en kø. Mere specifikt har du muligvis på samme tidspunkt, at flere producenter lagrer data og flere forbrugere henter dem fra et fælles datalager. Derfor har du brug for en ordentlig synkroniseringsmekanisme for at synkronisere adgangen til disse data.

Her er præcis, hvor BlockingCollection-klassen kommer til undsætning. Selvom der er mange andre måder, giver denne klasse en af ​​de mest effektive måder at synkronisere adgang til dine data på. Klassen BlockingCollection hører til System.Collections.Concurrent navneområdet.

Hvad er en BlockingCollection?

BlockingCollection er en trådsikker samling, hvor du kan få flere tråde til at tilføje og fjerne data samtidigt. Det er repræsenteret i .Net gennem klassen BlockingCollection; du kan bruge denne klasse til at implementere et producent-forbruger mønster.

I producent-forbruger mønster har du to forskellige komponenter, der kører på to forskellige tråde. Disse inkluderer en producentkomponent, der producerer nogle data, der skubbes til køen, og en forbruger, der forbruger de data, der er gemt i køen. Når du bruger en BlockingCollection, kan du angive den afgrænsede kapacitet samt typen af ​​den samling, du vil bruge.

BlockingCollection-typen fungerer som en indpakning over en forekomst af typen IProducerConsumerCollection. Med andre ord fungerer det som en indpakning over en anden samling, som igen implementerer IProducerConsumerCollection-grænsefladen. Som et eksempel kan klasserne ConcurrentBag, ConcurrentQueue og ConcurrentStack bruges med en BlockingCollection, da alle implementerer grænsefladen IProducerConsumerCollection.

Bemærk, at IProducerConsumerCollection-grænsefladen indeholder erklæring om metoder, der kan bruges til at arbejde med trådsikre samlinger. MSDN siger: "Definerer metoder til at manipulere trådsikre samlinger beregnet til producent / forbrugerbrug. Denne grænseflade giver en samlet repræsentation for producent / forbrugersamling, så abstraktioner på højere niveau såsom System.Collections.Concurrent.BlockingCollection kan bruge samlingen som den underliggende lagringsmekanisme. "

Følgende kodestykke viser, hvordan du kan oprette en forekomst af en BlockingCollection af strenge.

var blockingCollection = ny BlockingCollection ();

Når du bruger en BlockingCollection, kan du tilføje data til samlingen enten ved hjælp af Tilføj-metoden eller TryAdd-metoden. Lad os nu forstå forskellen mellem disse to metoder.

BlockingCollection data = ny BlockingCollection (boundedCapacity: 3);

data.Tilføj (1);

data.Tilføj (2);

data.Tilføj (3);

data.Tilføj (4); // Dette blokerer, indtil et element fjernes fra samlingen.

Bemærk, hvordan vi har specificeret boundedCapacity, når vi opretter en forekomst af en BlockingCollection som vist i kodeuddraget ovenfor. Dette er angivet for at angive den afgrænsede størrelse af samlingsinstansen.

Du kan også bruge TryAdd-metoden til at føje et element til en BlockingCollection-forekomst. I denne metode kan du bruge en timeout-værdi. Hvis tilføjelsesoperationen mislykkes inden for den angivne tid, returnerer TryAdd-metoden falsk. Følgende kodestykke viser, hvordan du kan udnytte TryAdd-metoden til at føje et element til en forekomst af BlockingCollection.

BlockingCollection data = ny BlockingCollection (boundedCapacity: 3);

data.Tilføj (1);

data.Tilføj (2);

data.Tilføj (3);

hvis (data.TryAdd (4, TimeSpan.FromMilliseconds (100)))

{

Console.WriteLine ("Et nyt element blev tilføjet til samlingen.");

}

andet

{

Console.WriteLine ("Kunne ikke tilføje et nyt element til samlingen.");

}

For at fjerne et element fra en BlockingCollection kan du bruge Take- eller TryTake-metoden. Bemærk, at Take-metoden blokeres, hvis der ikke er nogen genstande i samlingen og fjerner blokeringen, så snart et nyt element føjes til samlingen. TryTake-metoden kan også bruges til at fjerne et element fra en forekomst af en BlockingCollection. Du kan angive en timeout-værdi med denne metode, så metoden blokeres (indtil den angivne tid går), indtil et element føjes til samlingen. Hvis et element ikke kunne fjernes fra samlingen i løbet af dette tidsrum (den angivne timeout), returnerer TryTake-metoden falsk.

Følgende kodestykke illustrerer, hvordan TryTake-metoden kan bruges til at fjerne et element fra en forekomst af typen BlockingCollection.

int-vare;

while (data.TryTake (ud element, TimeSpan.FromMilliseconds (100)))

{

Console.WriteLine (vare);

}

Her er en komplet kodeliste til din reference. Dette program illustrerer, hvordan du kan bruge en BlockingCollection til at tilføje og fjerne emner til og fra en samling.

klasse Program

   {

private statiske BlockingCollection data = nye BlockingCollection ();

privat statisk tomrum Producent ()

       {

for (int ctr = 0; ctr <10; ctr ++)

           {

data.Tilføj (ctr);

Tråd. Søvn (100);

           }

       }

privat statisk ugyldig forbruger ()

       {

foreach (var element i data.GetConsumingEnumerable ())

           {

Console.WriteLine (vare);

           }

       }

statisk ugyldigt Main (streng [] args)

       {

var producent = Task.Factory.StartNew (() => Producent ());

var forbruger = Task.Factory.StartNew (() => Forbruger ());

Console.Read ();

       }

   }