Programmering

Hvordan jobbe med BlockingCollection i C #

Tenk på et scenario der flere tråder vil lese og skrive til en kø. Mer spesifikt kan det hende at du på samme tidspunkt har lagret flere produsenter og flere forbrukere som henter dem fra en felles datalager. Derfor vil du trenge en riktig synkroniseringsmekanisme for å synkronisere tilgangen til disse dataene.

Her er nøyaktig hvor BlockingCollection-klassen kommer til unnsetning. Selv om det er mange andre måter, gir denne klassen en av de mest effektive måtene å synkronisere tilgang til dataene dine. BlockingCollection-klassen tilhører System.Collections.Concurrent navneområdet.

Hva er en BlockingCollection?

BlockingCollection er en trådsikker samling der du kan la flere tråder legge til og fjerne data samtidig. Den er representert i .Net gjennom BlockingCollection-klassen; du kan bruke denne klassen til å implementere et produsent-forbrukermønster.

I produsent-forbruker-mønsteret har du to forskjellige komponenter som kjører på to forskjellige tråder. Disse inkluderer en produsentkomponent som produserer noen data som skyves til køen, og en forbruker som forbruker dataene som er lagret i køen. Når du bruker en BlockingCollection, kan du spesifisere den avgrensede kapasiteten samt typen samlingen du vil bruke.

BlockingCollection-typen fungerer som en omslag over en forekomst av typen IProducerConsumerCollection. Med andre ord fungerer den som en innpakning over en annen samling som igjen implementerer IProducerConsumerCollection-grensesnittet. Som et eksempel kan klassene ConcurrentBag, ConcurrentQueue og ConcurrentStack brukes med en BlockingCollection siden alle implementerer IProducerConsumerCollection-grensesnittet.

Merk at grensesnittet for IProducerConsumerCollection inneholder erklæring om metoder som kan brukes til å arbeide med trådsikre samlinger. MSDN sier: "Definerer metoder for å manipulere trådsikre samlinger beregnet på produsent / forbrukerbruk. Dette grensesnittet gir en enhetlig representasjon for produsent / forbruker samlinger slik at høyere nivå abstraksjoner som System.Collections.Concurrent.BlockingCollection kan bruke samlingen som den underliggende lagringsmekanismen. "

Følgende kodebit viser hvordan du kan opprette en forekomst av en BlockingCollection of strings.

var blockingCollection = ny BlockingCollection ();

Når du bruker en BlockingCollection, kan du legge til data i samlingen enten ved hjelp av Add-metoden eller TryAdd-metoden. La oss nå forstå forskjellen mellom disse to metodene.

BlockingCollection data = new BlockingCollection (boundedCapacity: 3);

data.Legg til (1);

data.Legg til (2);

data.Legg til (3);

data.Legg til (4); // Dette vil blokkere til et element er fjernet fra samlingen.

Legg merke til hvordan vi har spesifisert boundedCapacity når vi oppretter en forekomst av en BlockingCollection som vist i kodebiten gitt ovenfor. Dette er spesifisert for å indikere den begrensede størrelsen på samlingsforekomsten.

Du kan også bruke TryAdd-metoden for å legge til et element i en BlockingCollection-forekomst. I denne metoden kan du bruke en timeout-verdi. Hvis tilleggsoperasjonen mislykkes innen den angitte tiden, returnerer TryAdd-metoden falsk. Følgende kodebit viser hvordan du kan dra nytte av TryAdd-metoden for å legge til et element i en forekomst av BlockingCollection.

BlockingCollection data = new BlockingCollection (boundedCapacity: 3);

data.Legg til (1);

data.Legg til (2);

data.Legg til (3);

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

{

Console.WriteLine ("Et nytt element ble lagt til i samlingen.");

}

ellers

{

Console.WriteLine ("Kunne ikke legge til et nytt element i samlingen.");

}

For å fjerne et element fra en BlockingCollection, kan du bruke metoden Take eller TryTake. Merk at Take-metoden blokkeres hvis det ikke er noen elementer i samlingen og opphever blokkeringen så snart et nytt element er lagt til samlingen. TryTake-metoden kan også brukes til å fjerne et element fra en forekomst av en BlockingCollection. Du kan spesifisere en tidsavbruddsverdi med denne metoden, slik at metoden blokkeres (til den angitte tiden går) til et element blir lagt til samlingen. Hvis et element ikke kunne fjernes fra samlingen i løpet av denne tidsperioden (angitt tidsavbrudd), returnerer TryTake-metoden false.

Følgende kodebit illustrerer hvordan TryTake-metoden kan brukes til å fjerne et element fra en forekomst av typen BlockingCollection.

int element;

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

{

Console.WriteLine (vare);

}

Her er en komplett kodeliste for din referanse. Dette programmet illustrerer hvordan du kan bruke en BlockingCollection til å legge til og fjerne elementer til og fra en samling.

klasse Program

   {

private statiske BlockingCollection data = nye BlockingCollection ();

privat statisk tomrom Produsent ()

       {

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

           {

data.Add (ctr);

Tråd. Søvn (100);

           }

       }

privat statisk ugyldig Forbruker ()

       {

foreach (var element i data.GetConsumingEnumerable ())

           {

Console.WriteLine (vare);

           }

       }

statisk tomrom Main (streng [] args)

       {

var produsent = Task.Factory.StartNew (() => Produsent ());

var forbruker = Task.Factory.StartNew (() => Forbruker ());

Console.Read ();

       }

   }

$config[zx-auto] not found$config[zx-overlay] not found