.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.