Programovanie

Ako pracovať s BlockingCollection v C #

Zvážte scenár, keď by viac vlákien čítalo a zapisovalo do frontu. Presnejšie povedané, v rovnakom čase môžete mať viac výrobcov, ktorí ukladajú údaje, a viacerí spotrebitelia ich načítajú zo spoločného úložiska údajov. Preto by ste potrebovali správny synchronizačný mechanizmus, aby ste synchronizovali prístup k týmto údajom.

Tu je presne miesto, kde príde na pomoc trieda BlockingCollection. Aj keď existuje veľa ďalších spôsobov, táto trieda poskytuje jeden z najefektívnejších spôsobov synchronizácie prístupu k vašim údajom. Trieda BlockingCollection patrí do menného priestoru System.Collections.Concurrent.

Čo je BlockingCollection?

BlockingCollection je kolekcia bezpečná pre vlákna, v ktorej môžete mať k dispozícii viac vlákien na súčasné pridávanie a odstraňovanie údajov. Je zastúpená v .Net prostredníctvom triedy BlockingCollection; túto triedu môžete použiť na implementáciu modelu producent - spotrebiteľ.

Vo vzore producent-spotrebiteľ máte dve odlišné komponenty, ktoré fungujú na dvoch rôznych vláknach. Patria sem produkčný komponent, ktorý produkuje niektoré údaje, ktoré sa posúvajú do fronty, a spotrebiteľ, ktorý spotrebúva dáta, ktoré sú uložené vo fronte. Ak používate BlockingCollection, môžete určiť obmedzenú kapacitu a typ kolekcie, ktorú chcete použiť.

Typ BlockingCollection funguje ako obálka nad inštanciou typu IProducerConsumerCollection. Inými slovami, funguje ako obal nad inou kolekciou, ktorá zase implementuje rozhranie IProducerConsumerCollection. Napríklad triedy ConcurrentBag, ConcurrentQueue a ConcurrentStack môžu byť použité s BlockingCollection, pretože všetky implementujú rozhranie IProducerConsumerCollection.

Upozorňujeme, že rozhranie IProducerConsumerCollection obsahuje deklaráciu metód, ktoré možno použiť na prácu s kolekciami bezpečnými pre vlákna. MSDN uvádza: „Definuje metódy na manipuláciu so zbierkami bezpečnými pre vlákna určenými pre použitie výrobcom / spotrebiteľom. Toto rozhranie poskytuje jednotné zastúpenie pre zbierky výrobcov / spotrebiteľov, aby abstrakcie vyššej úrovne, ako napríklad System.Collections.Concurrent.BlockingCollection, mohli zbierku používať ako základný mechanizmus ukladania. “

Nasledujúci úryvok kódu ukazuje, ako môžete vytvoriť inštanciu reťazca BlockingCollection.

var blockingCollection = nový BlockingCollection ();

Pri použití BlockingCollection môžete do zbierky pridať údaje buď pomocou metódy Add, alebo TryAdd. Poďme teraz pochopiť rozdiel medzi týmito dvoma metódami.

BlockingCollection data = new BlockingCollection (boundedCapacity: 3);

data.Add (1);

data.Add (2);

data.Add (3);

data.Add (4); // Toto by sa zablokovalo, kým nebude položka odstránená zo zbierky.

Všimnite si, ako sme určili boundedCapacity pri vytváraní inštancie BlockingCollection, ako je uvedené v úryvku kódu uvedenom vyššie. Toto je určené na označenie obmedzenej veľkosti inštancie kolekcie.

Môžete tiež použiť metódu TryAdd na pridanie položky do inštancie BlockingCollection. V tejto metóde môžete použiť hodnotu časového limitu. Ak operácia pridania zlyhá v stanovenom čase, metóda TryAdd vráti hodnotu false. Nasledujúci úryvok kódu ukazuje, ako môžete využiť metódu TryAdd na pridanie položky do inštancie BlockingCollection.

BlockingCollection data = new BlockingCollection (boundedCapacity: 3);

data.Add (1);

data.Add (2);

data.Add (3);

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

{

Console.WriteLine („Do zbierky bola úspešne pridaná nová položka.“);

}

inak

{

Console.WriteLine ("Nepodarilo sa pridať novú položku do kolekcie.");

}

Ak chcete odstrániť položku z BlockingCollection, môžete použiť metódu Take alebo TryTake. Upozorňujeme, že metóda Take blokuje, ak v zbierke nie sú žiadne položky, a odblokuje sa, akonáhle je do zbierky pridaná nová položka. Metódu TryTake možno použiť aj na odstránenie položky z inštancie BlockingCollection. Pri tejto metóde môžete určiť hodnotu časového limitu, aby metóda blokovala (kým neuplynie zadaný čas), kým sa do kolekcie nepridá položka. Ak počas tohto času nebolo možné položku zo zbierky odstrániť (zadaný časový limit), metóda TryTake vráti hodnotu false.

Nasledujúci úryvok kódu ilustruje, ako je možné použiť metódu TryTake na odstránenie položky z inštancie typu BlockingCollection.

položka int;

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

{

Console.WriteLine (položka);

}

Tu je kompletný zoznam kódov pre vašu referenciu. Tento program ilustruje, ako môžete použiť BlockingCollection na pridávanie a odstraňovanie položiek do a zo zbierky.

triedny program

   {

private static BlockingCollection data = new BlockingCollection ();

private static void Producer ()

       {

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

           {

data.Add (ctr);

Závit. Spánok (100);

           }

       }

private static void Consumer ()

       {

foreach (var položka v data.GetConsumingEnumerable ())

           {

Console.WriteLine (položka);

           }

       }

static void Main (reťazec [] args)

       {

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

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

Console.Read ();

       }

   }

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