Ohjelmointi

Kuinka käyttää BlockingCollectionia C #: ssä

Tarkastellaan skenaariota, jossa useita säikeitä lukisi ja kirjoitettaisiin jonoon. Tarkemmin sanottuna sinulla voi olla samaan aikaan useita tuottajia, jotka tallentavat tietoja ja useat kuluttajat noutavat ne yhteisestä tietovarastosta. Tarvitset siis oikean synkronointimekanismin synkronoidaksesi pääsyn näihin tietoihin.

Tässä tarkalleen missä BlockingCollection-luokka tulee pelastamaan. Vaikka on olemassa monia muita tapoja, tämä luokka tarjoaa yhden tehokkaimmista tavoista synkronoida pääsy tietoihisi. BlockingCollection-luokka kuuluu System.Collections.Concurrent-nimitilaan.

Mikä on BlockingCollection?

BlockingCollection on ketjuturvallinen kokoelma, jossa voit pyytää useita ketjuja lisäämään ja poistamaan tietoja samanaikaisesti. Sitä edustaa .Net BlockingCollection-luokan kautta; voit käyttää tätä luokkaa tuottaja-kuluttaja-mallin toteuttamiseksi.

Tuottaja-kuluttaja-mallissa sinulla on kaksi erillistä komponenttia, jotka toimivat kahdella eri säikeellä. Näitä ovat tuottajakomponentti, joka tuottaa joitain tietoja, jotka työnnetään jonoon, ja kuluttaja, jotka kuluttavat jonoon tallennetut tiedot. Kun käytät BlockingCollection-ohjelmaa, voit määrittää rajatun kapasiteetin ja käytettävän kokoelman tyypin.

BlockingCollection-tyyppi toimii kääreenä tyypin IProducerConsumerCollection esiintymän yli. Toisin sanoen se toimii kääreenä toisen kokoelman päällä, joka puolestaan ​​toteuttaa IProducerConsumerCollection-käyttöliittymän. Esimerkiksi ConcurrentBag-, ConcurrentQueue- ja ConcurrentStack-luokkia voidaan käyttää BlockingCollection-sovelluksen kanssa, koska ne kaikki käyttävät IProducerConsumerCollection-rajapintaa.

Huomaa, että IProducerConsumerCollection-käyttöliittymä sisältää ilmoituksen menetelmistä, joita voidaan käyttää ketjuturvallisten kokoelmien kanssa. MSDN toteaa: "Määrittää menetelmät tuottaja- / kuluttajakäyttöön tarkoitettujen langattomien kokoelmien manipuloimiseksi. Tämä käyttöliittymä tarjoaa yhtenäisen edustuksen tuottaja- / kuluttajakokoelmille, jotta korkeamman tason abstraktit, kuten System.Collections.Concurrent.BlockingCollection, voivat käyttää kokoelmaa taustalla olevaan tallennusmekanismiin. "

Seuraava koodinpätkä osoittaa, kuinka voit luoda merkkijonojen BlockingCollection-ilmentymän.

var blockingCollection = uusi BlockingCollection ();

Kun käytät BlockingCollection-ohjelmaa, voit lisätä tietoja kokoelmaan joko Lisää- tai TryAdd-menetelmällä. Ymmärretään nyt näiden kahden menetelmän ero.

BlockingCollection data = uusi BlockingCollection (rajoitettu kapasiteetti: 3);

data.Lisää (1);

data.Lisää (2);

data.Lisää (3);

data.Lisää (4); // Tämä estäisi, kunnes kohde poistetaan kokoelmasta.

Huomaa, kuinka olemme määritelleet rajoitetun kapasiteetin luodessamme BlockingCollection-instanssia yllä olevan koodinpätkän mukaisesti. Tämä on määritetty osoittamaan kokoelman esiintymän rajoitettua kokoa.

Voit lisätä kohteen BlockingCollection-ilmentymään myös TryAdd-menetelmällä. Tässä menetelmässä voit käyttää aikakatkaisuarvoa. Jos lisäystoiminto epäonnistuu määritetyn ajan kuluessa, TryAdd-menetelmä palauttaa arvon false. Seuraava koodinpätkä osoittaa, kuinka voit hyödyntää TryAdd-menetelmää ja lisätä kohteen BlockingCollection-esiintymään.

BlockingCollection data = uusi BlockingCollection (rajoitettu kapasiteetti: 3);

data.Lisää (1);

data.Lisää (2);

data.Lisää (3);

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

{

Console.WriteLine ("Uusi kohde lisättiin onnistuneesti kokoelmaan.");

}

muu

{

Console.WriteLine ("Uuden kohteen lisääminen kokoelmaan epäonnistui.");

}

Voit poistaa kohteen BlockingCollectionista käyttämällä Take- tai TryTake-menetelmää. Huomaa, että Take-menetelmä estää, jos kokoelmassa ei ole kohteita, ja poistaa eston heti, kun uusi kohde lisätään kokoelmaan. TryTake-menetelmää voidaan käyttää myös kohteen poistamiseen BlockingCollection-esiintymästä. Voit määrittää aikakatkaisun arvon tällä menetelmällä niin, että menetelmä estää (kunnes määritetty aika kuluu), kunnes kohde lisätään kokoelmaan. Jos kohdetta ei voitu poistaa kokoelmasta tänä aikana (määritetty aikakatkaisu), TryTake-menetelmä palauttaa arvon false.

Seuraava koodinpätkä kuvaa, kuinka TryTake-menetelmää voidaan käyttää kohteen poistamiseen BlockingCollection-tyyppisestä ilmentymästä.

int tuote;

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

{

Console.WriteLine (kohde);

}

Tässä on täydellinen koodiluettelo viitteellesi. Tämä ohjelma kuvaa, kuinka voit käyttää BlockingCollection-sovellusta lisätäksesi ja poistaaksesi kohteita kokoelmaan ja sieltä.

luokan ohjelma

   {

yksityinen staattinen BlockingCollection-data = uusi BlockingCollection ();

yksityinen staattinen mitätön Tuottaja ()

       {

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

           {

data.Add (ctr);

Lanka.Nukkuva (100);

           }

       }

yksityinen staattinen tyhjä Kuluttaja ()

       {

foreach (muuttuja data.GetConsumingEnumerable ())

           {

Console.WriteLine (kohde);

           }

       }

staattinen void Main (merkkijono [] args)

       {

var producer = Tehtävä.Tehdas.StartNew (() => Tuottaja ());

var kuluttaja = Task.Factory.StartNew (() => Consumer ());

Konsoli.Lue ();

       }

   }

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