Programmering

Sådan arbejder du med ConcurrentBag og ConcurrentDictionary i .Net

Samtidige samlinger i .Net er indeholdt i System.Collections.Concurrent navneområde og giver låsefri og trådsikker implementering af samlingsklasserne. Trådsikre samlinger blev først introduceret i .Net 4, og samlinger blev først introduceret som en del af. Net Framework 1.0 og var tilgængelige i System.Collections-navneområdet.

Du kan drage fordel af de samtidige samlinger til at arbejde med samlinger uden behov for at skulle skrive en ekstra kode til trådsynkronisering. Du kan se min artikel om ConcurrentStack og ConcurrentQueue.

ConcurrentBag

ConcurrentBag giver en trådsikker samling af et uordnet sæt af elementer. Her er listen over de vigtige metoder i ConcurrentBag-klassen.

  • Tilføj (T-element) - Denne metode bruges til at føje et element til ConcurrentBag.
  • TryPeek (ud T) - Denne metode bruges til at hente et element fra ConcurrentBag uden at fjerne det.
  • TryTake (ud T) - Denne metode bruges til at hente et element fra ConcurrentBag. Bemærk, at denne metode fjerner elementet fra samlingen.

Følgende kodestykke illustrerer, hvordan du kan oprette en ConcurrentBag-samling og gemme varer i den.

ConcurrentBag concurrentBag = ny ConcurrentBag ();

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

    {

concurrentBag.Add (i);

    }

Hvis du skulle hente varerne i samlingen, skal du skrive følgende kode:

while (concurrentBag.Count> 0)

  {

Int32 element;

if (concurrentBag.TryTake (ud-element))

       {

Console.WriteLine (element);

       }

  }

Bemærk, hvordan TryTake-metoden er blevet brugt: Den returnerer sandt efter succes, ellers falsk. TryTake-metoden fjerner også elementet fra samlingen. While-løkken fortsætter udførelsen, indtil antallet af varer i samlingen er større end nul. Her er den komplette kodeliste til din reference.

statisk ugyldigt 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 (ud-element))

                {

Console.WriteLine (element);

                }

            }

Console.Read ();

        }

Samtidig ordbog

En ordbog er en generisk samling af nøgle / værdipar. Det er hurtigere end en Hashtable, da det eliminerer bokse- og un-boks-omkostninger. ConcurrentDictionary er indeholdt i System.Collections.Concurrent navneområdet og repræsenterer en trådsikker ordbog.

De vigtige medlemmer af klassen ConcurrentDictionary inkluderer følgende:

  • TryAdd: Denne metode bruges til at tilføje et element i ConcurrentDictionary-forekomsten. Bemærk, at denne metode giver en undtagelse, hvis nøglen allerede er til stede i samlingen.
  • TryGetValue: Denne metode bruges til at hente et element fra samlingen.
  • TryRemove: Denne metode bruges til at fjerne et element fra samlingen.
  • TryUpdate: Denne metode bruges til at opdatere en bestemt nøgle i ConcurrentDictionary-forekomsten med den nye leverede værdi.

Følgende kodestykke viser, hvordan du kan oprette en ConcurrentDictionary-forekomst og tilføje elementer til den:

ConcurrentDictionary obj = ny ConcurrentDictionary ();

obj.TryAdd ("X001", "Dette er den første værdi.");

obj.TryAdd ("X002", "Dette er den anden værdi.");

Hvis du nu prøver at tilføje et andet element, men med den samme nøgle, mislykkes det. Se kodestykket nedenfor.

bool success = obj.TryAdd ("X002", "Dette er den tredje værdi.");

Værdien af ​​succesvariablen er "falsk", da forsøget på at tilføje en værdi med den samme nøgle mislykkes.

Følgende kodestykke illustrerer, hvordan du kan hente et element fra samlingen baseret på en nøgle.

streng element = null;

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

Hvis du skulle hente alle elementerne i samlingen, kan du bruge følgende kodestykke i stedet.

foreach (var v in obj)

    {

Console.WriteLine (v.Key + "---" + v.Værdi);

    }

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

streng element = null;

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

Hvis du fjernede alle elementer, kunne følgende kodestykke bruges i stedet.

obj.Clear ();

Overvej nu 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);

            }

        }

Her er hvordan du kan udføre de to ovennævnte metoder på to opgaveforekomster samtidigt - en til at gemme værdier i samlingen og den anden til at læse værdier fra samlingen.

ConcurrentDictionary obj = ny ConcurrentDictionary ();

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

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

prøve

{

Task.WaitAll (firstTask, secondTask);

}

fange (AggregateException ex)

{

// Skriv din egen kode her for at håndtere undtagelse

}

Hvis du udfører ovenstående kode, vil undtagelse ikke blive kastet, da samlingen her er trådsikker.