Programiranje

Kako delati z BlockingCollection v C #

Razmislite o scenariju, ko bi več niti bralo in zapisovalo v čakalno vrsto. Natančneje, morda imate ob istem času več proizvajalcev, ki hranijo podatke, več potrošnikov pa jih pridobiva iz skupne shrambe podatkov. Zato bi za sinhronizacijo dostopa do teh podatkov potrebovali ustrezen mehanizem za sinhronizacijo.

Tukaj na pomoč priskoči razred BlockingCollection. Čeprav obstaja veliko drugih načinov, ta razred ponuja enega najučinkovitejših načinov za sinhronizacijo dostopa do vaših podatkov. Razred BlockingCollection spada v imenski prostor System.Collections.Concurrent.

Kaj je BlockingCollection?

BlockingCollection je nit-varna zbirka, v kateri lahko več niti sočasno dodaja in odstranjuje podatke. V .Net je predstavljen skozi razred BlockingCollection; ta razred lahko uporabite za izvajanje vzorca proizvajalec-potrošnik.

V vzorcu proizvajalec-potrošnik imate dve različni komponenti, ki delujeta na dveh različnih nitih. Sem spadajo komponenta proizvajalca, ki ustvari nekatere podatke, ki se potisnejo v čakalno vrsto, in potrošnik, ki porabi podatke, shranjene v čakalni vrsti. Ko uporabljate BlockingCollection, lahko določite omejeno kapaciteto in vrsto zbirke, ki jo želite uporabiti.

Tip BlockingCollection deluje kot ovoj nad primerkom tipa IProducerConsumerCollection. Z drugimi besedami, deluje kot ovoj nad drugo zbirko, ki nato implementira vmesnik IProducerConsumerCollection. Kot primer lahko razrede ConcurrentBag, ConcurrentQueue in ConcurrentStack uporabimo z BlockingCollection, saj vsi izvajajo vmesnik IProducerConsumerCollection.

Upoštevajte, da vmesnik IProducerConsumerCollection vsebuje izjavo o metodah, ki se lahko uporabljajo za delo z zbirkami, varnimi za nit. MSDN navaja: "Določa metode za upravljanje z zbirkami, varnimi za navoje, namenjene za uporabo proizvajalcev / potrošnikov. Ta vmesnik zagotavlja enotno predstavitev zbirk proizvajalcev / potrošnikov, tako da lahko abstrakcije višje ravni, kot je System.Collections.Concurrent.BlockingCollection, uporabijo zbirko kot osnovni mehanizem za shranjevanje. "

Naslednji delček kode prikazuje, kako lahko ustvarite primerek BlockingCollection nizov.

var blockingCollection = novo BlockingCollection ();

Ko uporabljate BlockingCollection, lahko zbirki dodate podatke z uporabo metode Add ali TryAdd. Zdaj pa razumimo razliko med tema dvema metodama.

Podatki BlockingCollection = novo BlockingCollection (boundedCapacity: 3);

data.Add (1);

data.Add (2);

data.Add (3);

data.Add (4); // To bi blokiralo, dokler element ni odstranjen iz zbirke.

Upoštevajte, kako smo določili omejeno zmogljivost pri ustvarjanju primerka BlockingCollection, kot je prikazano v zgornjem delčku kode. To je določeno, da označi omejeno velikost primerka zbirke.

Lahko uporabite tudi metodo TryAdd, če želite dodati element v primerek BlockingCollection. Pri tej metodi lahko uporabite vrednost časovne omejitve. Če operacija dodajanja v določenem času ne uspe, metoda TryAdd vrne false. Naslednji delček kode prikazuje, kako lahko s pomočjo metode TryAdd dodate element v primerek BlockingCollection.

Podatki BlockingCollection = novo BlockingCollection (boundedCapacity: 3);

data.Add (1);

data.Add (2);

data.Add (3);

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

{

Console.WriteLine ("Nov element je bil uspešno dodan v zbirko.");

}

drugače

{

Console.WriteLine ("Ni bilo mogoče dodati novega elementa v zbirko.");

}

Če želite element odstraniti iz zbirke BlockingCollection, lahko uporabite metodo Take ali TryTake. Upoštevajte, da metoda »Take« blokira, če v zbirki ni elementov, in se odblokira takoj, ko je novi element dodan v zbirko. Z metodo TryTake lahko tudi odstranite element iz primerka BlockingCollection. S to metodo lahko določite vrednost časovne omejitve, tako da metoda blokira (dokler ne poteče določen čas), dokler element ni dodan v zbirko. Če elementa v tem času ni bilo mogoče odstraniti iz zbirke (določena časovna omejitev), metoda TryTake vrne false.

Naslednji delček kode prikazuje, kako je mogoče metodo TryTake uporabiti za odstranitev predmeta iz primerka vrste BlockingCollection.

int element;

while (data.TryTake (out item, TimeSpan.FromMilliseconds (100)))

{

Console.WriteLine (element);

}

Tu je popoln seznam kod za vašo referenco. Ta program ponazarja, kako lahko z zbirko BlockingCollection dodate in odstranite elemente iz zbirke in iz nje.

razredni program

   {

zasebni statični podatki BlockingCollection = novo BlockingCollection ();

zasebna statična praznina Producer ()

       {

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

           {

data.Add (ctr);

Navoj.spanje (100);

           }

       }

zasebna statična praznina Potrošnik ()

       {

foreach (element postavke v podatkih. GetConsumingEnumerable ())

           {

Console.WriteLine (element);

           }

       }

statična praznina Main (string [] args)

       {

var proizvajalec = Task.Factory.StartNew (() => Producer ());

var potrošnik = Task.Factory.StartNew (() => Potrošnik ());

Console.Read ();

       }

   }

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