Programmering

Hvordan jobbe med ConcurrentBag og ConcurrentDictionary i .Net

Samtidige samlinger i .Net er inneholdt i System.Collections.Concurrent navneområdet og gir låsfrie og trådsikre implementeringer av samlingsklassene. Trådsikre samlinger ble først introdusert i .Net 4, og samlinger ble først introdusert som en del av .Net Framework 1.0 og var tilgjengelige i navneområdet System.Collections.

Du kan dra nytte av samtidige samlinger for å jobbe med samlinger uten behov for å måtte skrive ekstra kode for trådsynkronisering. Du kan ta en titt på artikkelen min om ConcurrentStack og ConcurrentQueue.

ConcurrentBag

ConcurrentBag gir en trådsikker samling av et uordnet sett med elementer. Her er listen over viktige metoder i ConcurrentBag-klassen.

  • Add (T element) - Denne metoden brukes til å legge til et element i ConcurrentBag.
  • TryPeek (ut T) - Denne metoden brukes til å hente et element fra ConcurrentBag uten å fjerne det.
  • TryTake (ut T) - Denne metoden brukes til å hente et element fra ConcurrentBag. Merk at denne metoden fjerner varen fra samlingen.

Følgende kodebit illustrerer hvordan du kan lage en ConcurrentBag-samling og lagre varer i den.

ConcurrentBag concurrentBag = ny ConcurrentBag ();

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

    {

concurrentBag.Add (i);

    }

Hvis du skulle hente elementene i samlingen, bør du skrive følgende kode:

while (concurrentBag.Count> 0)

  {

Int32 element;

if (concurrentBag.TryTake (ut element))

       {

Console.WriteLine (element);

       }

  }

Legg merke til hvordan TryTake-metoden har blitt brukt: Den returnerer til suksess, ellers falsk. TryTake-metoden fjerner også varen fra samlingen. Mens loop fortsetter kjøringen til tidspunktet hvor antall varer i samlingen er større enn null. Her er den komplette kodelisten som referanse.

statisk tomrom Main (streng [] args)

        {

ConcurrentBag concurrentBag = ny ConcurrentBag ();

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

            {

concurrentBag.Add (i);

            }

while (concurrentBag.Count> 0)

            {

Int32 element;

if (concurrentBag.TryTake (ut element))

                {

Console.WriteLine (element);

                }

            }

Console.Read ();

        }

Samtidig ordbok

En ordbok er en generisk samling av nøkkel / verdipar. Det er raskere enn en Hashtable, da det eliminerer boksing og un-boksing overhead. ConcurrentDictionary er inneholdt i navneområdet System.Collections.Concurrent og representerer en trådsikker ordbok.

De viktige medlemmene av ConcurrentDictionary-klassen inkluderer følgende:

  • TryAdd: Denne metoden brukes til å legge til et element i ConcurrentDictionary-forekomsten. Merk at denne metoden gir et unntak hvis nøkkelen allerede er tilstede i samlingen.
  • TryGetValue: Denne metoden brukes til å hente et element fra samlingen.
  • TryRemove: Denne metoden brukes til å fjerne et element fra samlingen.
  • TryUpdate: Denne metoden brukes til å oppdatere en bestemt nøkkel i ConcurrentDictionary-forekomsten med den nye verdien som er levert.

Følgende kodebit viser hvordan du kan opprette en ConcurrentDictionary-forekomst og legge til elementer i den:

ConcurrentDictionary obj = ny ConcurrentDictionary ();

obj.TryAdd ("X001", "Dette er den første verdien.");

obj.TryAdd ("X002", "Dette er den andre verdien.");

Hvis du nå prøver å legge til et annet element, men med samme nøkkel, mislykkes det. Se kodebiten nedenfor.

bool suksess = obj.TryAdd ("X002", "Dette er den tredje verdien.");

Verdien av suksessvariabelen er "falsk" ettersom forsøket på å legge til en verdi med samme nøkkel mislykkes.

Følgende kodebit illustrerer hvordan du kan hente et element fra samlingen basert på en nøkkel.

streng element = null;

bool isExist = obj.TryGetValue ("X001", ut element);

Hvis du skulle hente alle elementene i samlingen, kan du bruke følgende kodebit i stedet.

foreach (var v in obj)

    {

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

    }

Følgende kodebit viser hvordan du kan fjerne et element fra samlingen.

streng element = null;

bool resultat = obj.TryRemove ("X001", ut element);

Hvis du skulle fjerne alle elementene, kan følgende kodebit brukes i stedet.

obj.Clear ();

Vurder nå følgende to statiske metoder.

statisk ugyldig FirstTask (ConcurrentDictionary obj)

        {

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

            {

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

Tråd. Søvn (100);

            }

        }

statisk ugyldig SecondTask (ConcurrentDictionary obj)

        {

Tråd.Søvn (1000);

foreach (var varen i obj)

            {

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

Tråd. Søvn (100);

            }

        }

Slik kan du utføre de to ovennevnte metodene på to oppgaveforekomster samtidig - en for å lagre verdier i samlingen og den andre for å lese verdier fra samlingen.

ConcurrentDictionary obj = ny ConcurrentDictionary ();

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

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

prøve

{

Task.WaitAll (firstTask, secondTask);

}

fange (AggregateException ex)

{

// Skriv din egen kode her for å håndtere unntak

}

Hvis du utfører ovennevnte kode, vil ikke unntak bli kastet da samlingen her er trådsikker.