Programmēšana

Kā strādāt ar ConcurrentBag un ConcurrentDictionary .Net

Vienlaicīgas .Net kolekcijas ir System.Collections.Concurrent nosaukumvietā un nodrošina kolekciju klases bez bloķēšanas un pavedieniem drošu ieviešanu. Diegu drošas kolekcijas pirmo reizi tika ieviestas .Net 4, un kolekcijas pirmo reizi tika ieviestas kā daļa no .Net Framework 1.0 un bija pieejamas sistēmā System.Collections.

Varat izmantot vienlaicīgo kolekciju priekšrocības, lai strādātu ar kolekcijām, un nepieciešamība rakstīt jebkuru papildu kodu pavedienu sinhronizēšanai. Jūs varat apskatīt manu rakstu par ConcurrentStack un ConcurrentQueue.

Vienlaicīgs soma

ConcurrentBag nodrošina nekontrolētu elementu komplekta drošu kolekciju. Šeit ir saraksts ar ConcurrentBag klases svarīgākajām metodēm.

  • Pievienot (T elements) - šo metodi izmanto, lai pievienotu elementu ConcurrentBag.
  • TryPeek (out T) - šo metodi izmanto, lai izgūtu elementu no ConcurrentBag, to nenoņemot.
  • TryTake (out T) - šo metodi izmanto, lai izgūtu elementu no ConcurrentBag. Ņemiet vērā, ka ar šo metodi vienums tiek noņemts no kolekcijas.

Šis koda fragments parāda, kā jūs varat izveidot ConcurrentBag kolekciju un tajā saglabāt vienumus.

ConcurrentBag concurrentBag = jauns ConcurrentBag ();

par (int i = 0; i <10; i ++)

    {

concurrentBag.Add (i);

    }

Ja jums būtu jāatgūst kolekcijas vienumi, jums vajadzētu uzrakstīt šādu kodu:

while (concurrentBag.Count> 0)

  {

Int32 elements;

ja (concurrentBag.TryTake (elements))

       {

Console.WriteLine (elements);

       }

  }

Ievērojiet, kā ir izmantota TryTake metode: tā atgriež patiesu pēc panākumiem, citādi - nepatiesa. Izmantojot TryTake metodi, vienums tiek noņemts arī no kolekcijas. Cilpa while turpina izpildi līdz laikam, kad kolekcijas vienību skaits ir lielāks par nulli. Šeit ir sniegts pilns kodu saraksts.

static void Main (virkne [] args)

        {

ConcurrentBag concurrentBag = jauns ConcurrentBag ();

par (int i = 0; i <10; i ++)

            {

concurrentBag.Add (i);

            }

while (concurrentBag.Count> 0)

            {

Int32 elements;

ja (concurrentBag.TryTake (elements))

                {

Console.WriteLine (elements);

                }

            }

Konsole. Lasīt ();

        }

Vienlaicīga vārdnīca

Vārdnīca ir vispārīgs atslēgu / vērtību pāru krājums. Tas ir ātrāks nekā Hashtable, jo tas novērš boksa un bez boksa pieskaitāmās izmaksas. ConcurrentDictionary atrodas System.Collections.Concurrent nosaukumvietā un apzīmē vītnei drošu vārdnīcu.

Svarīgākie ConcurrentDictionary klases dalībnieki ir šādi:

  • TryAdd: Šo metodi izmanto, lai pievienotu vienumu ConcurrentDictionary instancē. Ņemiet vērā, ka šī metode rada izņēmumu, ja atslēga jau atrodas kolekcijā.
  • TryGetValue: Šo metodi izmanto, lai izgūtu vienumu no kolekcijas.
  • TryRemove: Šo metodi izmanto, lai noņemtu vienumu no kolekcijas.
  • TryUpdate: Šī metode tiek izmantota, lai atjauninātu konkrētu atslēgu ConcurrentDictionary instancē ar jauno piegādāto vērtību.

Šis koda fragments parāda, kā varat izveidot ConcurrentDictionary instanci un pievienot tam vienumus:

ConcurrentDictionary obj = new ConcurrentDictionary ();

obj.TryAdd ("X001", "Šī ir pirmā vērtība.");

obj.TryAdd ("X002", "Šī ir otrā vērtība.");

Ja tagad mēģināt pievienot citu vienumu, bet ar to pašu atslēgu, tas neizdodas. Skatiet tālāk redzamo koda fragmentu.

bool panākumi = obj.TryAdd ("X002", "Šī ir trešā vērtība.");

Veiksmes mainīgā vērtība ir "false", jo mēģinājums pievienot vērtību ar to pašu atslēgu neizdodas.

Šis koda fragments parāda, kā jūs varat izgūt vienumu no kolekcijas, pamatojoties uz atslēgu.

virknes vienums = null;

bool isExist = obj.TryGetValue ("X001", out vienums);

Ja jūs izgūtu visus kolekcijas vienumus, tā vietā varētu izmantot šo koda fragmentu.

foreach (var v in obj)

    {

Console.WriteLine (v.Key + "---" + v.Value);

    }

Šis koda fragments parāda, kā jūs varat noņemt vienumu no kolekcijas.

virknes vienums = null;

bool rezultāts = obj.TryRemove ("X001", out vienums);

Ja noņemtu visus vienumus, tā vietā varētu izmantot šo koda fragmentu.

obj. Skaidrs ();

Tagad apsveriet šādas divas statiskās metodes.

static void FirstTask (ConcurrentDictionary obj)

        {

par (int i = 0; i <10; ++ i)

            {

obj.TryAdd (i.ToString (), i.ToString ());

Vītne.Guli (100);

            }

        }

static void SecondTask (ConcurrentDictionary obj)

        {

Vītne. Miega režīms (1000);

foreach (var obj obj)

            {

Console.WriteLine ("Key:" + item.Key + "Value:" + item.Value);

Vītne.Guli (100);

            }

        }

Lūk, kā jūs varat izpildīt iepriekš minētās divas metodes vienlaikus divos uzdevuma gadījumos - vienā, lai vērtības saglabātu kolekcijā, un otrā, lai lasītu vērtības no kolekcijas.

ConcurrentDictionary obj = new ConcurrentDictionary ();

Task firstTask = Task.Run (() => FirstTask (obj));

Task secondTask = Task.Run (() => SecondTask (obj));

mēģiniet

{

Task.WaitAll (firstTask, secondTask);

}

nozveja (AggregateException ex)

{

// Uzrakstiet savu kodu šeit, lai apstrādātu izņēmumu

}

Ja izpildīsit iepriekš minēto kodu, izņēmums netiks izmests, jo šeit esošā kolekcija ir droša ar pavedieniem.

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