Programiranje

Kako delati s programoma ConcurrentBag in ConcurrentDictionary v .Net

Sočasne zbirke v .Net so vsebovane znotraj imenskega prostora System.Collections.Concurrent in zagotavljajo izvedbe razredov zbirk brez zaklepanja in nitkov. Varne zbirke niti so bile prvič predstavljene v .Net 4, zbirke pa so bile prvič predstavljene kot del .Net Framework 1.0 in so bile na voljo v imenskem prostoru System.Collections.

Sočasne zbirke lahko izkoristite za delo z zbirkami, če ni treba napisati dodatne kode za sinhronizacijo niti. Oglejte si moj članek o ConcurrentStack in ConcurrentQueue.

ConcurrentBag

ConcurrentBag ponuja zbirko neurejenega nabora elementov, varno za nit. Tu je seznam pomembnih metod razreda ConcurrentBag.

  • Dodaj (element T) - Ta metoda se uporablja za dodajanje elementa v ConcurrentBag.
  • TryPeek (out T) - Ta metoda se uporablja za pridobivanje elementa iz ConcurrentBag, ne da bi ga odstranili.
  • TryTake (out T) - Ta metoda se uporablja za pridobivanje elementa iz ConcurrentBag. Upoštevajte, da ta metoda odstrani element iz zbirke.

Naslednji delček kode prikazuje, kako lahko ustvarite zbirko ConcurrentBag in vanjo shranite predmete.

ConcurrentBag concurrentBag = nov ConcurrentBag ();

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

    {

concurrentBag.Add (i);

    }

Če želite pridobiti predmete iz zbirke, morate napisati naslednjo kodo:

medtem ko (concurrentBag.Count> 0)

  {

Element Int32;

if (concurrentBag.TryTake (element out))

       {

Console.WriteLine (element);

       }

  }

Upoštevajte, kako je bila uporabljena metoda TryTake: ob uspehu vrne true, sicer pa false. Metoda TryTake tudi odstrani element iz zbirke. Zanka while nadaljuje izvajanje, dokler število elementov v zbirki ni večje od nič. Tukaj je celoten seznam kod za vašo referenco.

statična praznina Main (string [] args)

        {

ConcurrentBag concurrentBag = nov ConcurrentBag ();

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

            {

concurrentBag.Add (i);

            }

medtem ko (concurrentBag.Count> 0)

            {

Element Int32;

if (concurrentBag.TryTake (element out))

                {

Console.WriteLine (element);

                }

            }

Console.Read ();

        }

ConcurrentDictionary

Slovar je generična zbirka parov ključ / vrednost. Je hitrejši od Hashtable-a, saj odpravlja režijske stroške za boks in odstranjevanje boksa. ConcurrentDictionary je vsebovan znotraj imenskega prostora System.Collections.Concurrent in predstavlja slovar, varen do niti.

Pomembni člani razreda ConcurrentDictionary vključujejo naslednje:

  • TryAdd: Ta metoda se uporablja za dodajanje elementa v primerku ConcurrentDictionary. Ta metoda vrže izjemo, če je ključ že prisoten v zbirki.
  • TryGetValue: Ta metoda se uporablja za pridobivanje predmeta iz zbirke.
  • TryRemove: Ta metoda se uporablja za odstranjevanje predmeta iz zbirke.
  • TryUpdate: Ta metoda se uporablja za posodobitev določenega ključa v primerku ConcurrentDictionary z novo vrednostjo.

Naslednji delček kode prikazuje, kako lahko ustvarite primerek ConcurrentDictionary in mu dodate elemente:

ConcurrentDictionary obj = nov ConcurrentDictionary ();

obj.TryAdd ("X001", "To je prva vrednost.");

obj.TryAdd ("X002", "To je druga vrednost.");

Če zdaj poskusite dodati še en element, vendar z istim ključem, ne uspe. Glejte spodnji delček kode.

bool success = obj.TryAdd ("X002", "To je tretja vrednost.");

Vrednost spremenljivke uspeha je "false", saj poskus dodajanja vrednosti z istim ključem ne uspe.

Naslednji delček kode prikazuje, kako lahko na podlagi ključa pridobite element iz zbirke.

niz element = null;

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

Če bi morali pridobiti vse elemente v zbirki, bi lahko namesto tega uporabili naslednji delček kode.

foreach (var v in obj)

    {

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

    }

Naslednji delček kode prikazuje, kako lahko element odstranite iz zbirke.

niz element = null;

rezultat bool = obj.TryRemove ("X001", izhodni element);

Če bi odstranili vse elemente, bi lahko namesto tega uporabili naslednji delček kode.

obj.Clear ();

Zdaj pa razmislite o naslednjih dveh statičnih metodah.

statična praznina FirstTask (ConcurrentDictionary obj)

        {

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

            {

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

Navoj.spanje (100);

            }

        }

statična praznina SecondTask (ConcurrentDictionary obj)

        {

Navoj.spanje (1000);

foreach (var element v obj)

            {

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

Navoj.spanje (100);

            }

        }

Tukaj je opisano, kako lahko izvedete zgornji dve metodi hkrati v dveh primerkih opravil - enega za shranjevanje vrednosti v zbirko in drugega za branje vrednosti iz zbirke.

ConcurrentDictionary obj = nov ConcurrentDictionary ();

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

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

poskusite

{

Task.WaitAll (firstTask, secondTask);

}

catch (AggregateException ex)

{

// Tukaj napišite svojo kodo za obravnavo izjem

}

Če izvedete zgornjo kodo, izjema ne bo vržena, saj je zbirka tukaj varna za nit.

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