Ohjelmointi

Kuinka työskennellä ConcurrentBagin ja ConcurrentDictionaryn kanssa .Netissä

.Net-verkkoon sisältyvät samanaikaiset kokoelmat sisältyvät System.Collections.Concurrent-nimitilaan ja tarjoavat kokoelmaluokkien lukitsematon ja langattomasti toteutuksen. Langansuojatut kokoelmat esiteltiin ensin .Net 4: ssä, ja kokoelmat esiteltiin ensin osana .Net Framework 1.0: ta ja ne olivat saatavilla System.Collections-nimiavaruudessa.

Voit hyödyntää samanaikaisia ​​kokoelmia työskennellessäsi kokoelmien kanssa, eikä tarvetta kirjoittaa ylimääräistä koodia ketjujen synkronointia varten. Voit katsoa artikkelini ConcurrentStackista ja ConcurrentQueue.

SamanaikainenLaukku

ConcurrentBag tarjoaa säikeettömän kokoelman järjestämättömistä elementeistä. Tässä on luettelo ConcurrentBag-luokan tärkeistä menetelmistä.

  • Lisää (T-elementti) - Tätä menetelmää käytetään lisäämään elementti ConcurrentBagiin.
  • TryPeek (out T) - Tätä menetelmää käytetään noutamaan elementti ConcurrentBagista poistamatta sitä.
  • TryTake (out T) - Tätä menetelmää käytetään elementin hakemiseen ConcurrentBagista. Huomaa, että tämä menetelmä poistaa kohteen kokoelmasta.

Seuraava koodinpätkä kuvaa, kuinka voit luoda ConcurrentBag-kokoelman ja tallentaa siihen kohteita.

ConcurrentBag concurrentBag = uusi ConcurrentBag ();

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

    {

concurrentBag.Add (i);

    }

Jos haluat noutaa kokoelman kohteet, kirjoita seuraava koodi:

while (concurrentBag.Count> 0)

  {

Int32-elementti;

if (concurrentBag.TryTake (elementti ulos))

       {

Console.WriteLine (elementti);

       }

  }

Huomaa, miten TryTake-menetelmää on käytetty: Se palauttaa arvon tosi onnistumisen yhteydessä, muuten epätosi. TryTake-menetelmä poistaa kohteen myös kokoelmasta. While-silmukka jatkaa suoritusta, kunnes kokoelman kohteiden määrä on suurempi kuin nolla. Tässä on täydellinen koodiluettelo viitteellesi.

staattinen void Main (merkkijono [] args)

        {

ConcurrentBag concurrentBag = uusi ConcurrentBag ();

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

            {

concurrentBag.Add (i);

            }

while (concurrentBag.Count> 0)

            {

Int32-elementti;

if (concurrentBag.TryTake (elementti ulos))

                {

Console.WriteLine (elementti);

                }

            }

Konsoli.Lue ();

        }

Samanaikainen sanakirja

Sanakirja on yleinen kokoelma avain / arvo-pareja. Se on nopeampi kuin Hashtable, koska se eliminoi nyrkkeilyn ja nyrkkeilyn yleiskustannukset. ConcurrentDictionary sisältyy System.Collections.Concurrent-nimitilaan ja edustaa langankiertoista sanakirjaa.

ConcurrentDictionary-luokan tärkeitä jäseniä ovat seuraavat:

  • TryAdd: Tätä menetelmää käytetään kohteen lisäämiseen ConcurrentDictionary-ilmentymään. Huomaa, että tämä menetelmä muodostaa poikkeuksen, jos avain on jo kokoelmassa.
  • TryGetValue: Tätä menetelmää käytetään kohteen noutamiseen kokoelmasta.
  • TryRemove: Tätä menetelmää käytetään kohteen poistamiseen kokoelmasta.
  • TryUpdate: Tätä menetelmää käytetään päivittämään tietty avain ConcurrentDictionary-ilmentymässä uudella toimitetulla arvolla.

Seuraava koodinpätkä näyttää, miten voit luoda ConcurrentDictionary-ilmentymän ja lisätä siihen kohteita:

ConcurrentDictionary obj = uusi ConcurrentDictionary ();

obj.TryAdd ("X001", "Tämä on ensimmäinen arvo.");

obj.TryAdd ("X002", "Tämä on toinen arvo.");

Jos yrität nyt lisätä toisen kohteen samalla avaimella, se epäonnistuu. Katso alla oleva koodinpätkä.

bool menestys = obj.TryAdd ("X002", "Tämä on kolmas arvo.");

Menestysmuuttujan arvo on "false", koska yritys lisätä arvoa samalla avaimella epäonnistuu.

Seuraava koodinpätkä kuvaa, kuinka voit noutaa kohteen kokoelmasta avaimen perusteella.

merkkijono = null;

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

Jos haet kaikki kokoelman kohteet, voit käyttää sen sijaan seuraavaa koodinpätkää.

foreach (var v in obj)

    {

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

    }

Seuraava koodinpätkä näyttää, kuinka voit poistaa kohteen kokoelmasta.

merkkijono = null;

bool-tulos = obj.TryRemove ("X001", out-kohde);

Jos haluat poistaa kaikki kohteet, seuraavaa koodinpätkää voidaan käyttää sen sijaan.

obj Selkeä ();

Harkitse nyt kahta seuraavaa staattista menetelmää.

staattinen void FirstTask (ConcurrentDictionary obj)

        {

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

            {

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

Lanka.Nukkuva (100);

            }

        }

staattinen void SecondTask (ConcurrentDictionary obj)

        {

Lanka.Nukkuu (1000);

foreach (var obj in obj)

            {

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

Lanka.Nukkuva (100);

            }

        }

Näin voit suorittaa yllä mainitut kaksi tapaa kahdessa Tehtävä-ilmentymässä samanaikaisesti - yksi tallentaa arvot kokoelmaan ja toinen lukea arvoja kokoelmasta.

ConcurrentDictionary obj = uusi ConcurrentDictionary ();

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

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

yrittää

{

Task.WaitAll (firstTask, secondTask);

}

saalis (AggregateException ex)

{

// Kirjoita oma koodi tähän käsittelemään poikkeusta

}

Jos suoritat yllä olevan koodin, poikkeusta ei heitetä, koska kokoelma tässä on säiettä turvallinen.