Sdílet prostřednictvím


ConcurrentDictionary<TKey,TValue>.GetOrAdd Metoda

Definice

Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč již existuje.

Přetížení

GetOrAdd(TKey, Func<TKey,TValue>)

Pokud klíč ještě neexistuje, přidá dvojici klíč-hodnota do parametru ConcurrentDictionary<TKey,TValue> pomocí zadané funkce. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.

GetOrAdd(TKey, TValue)

Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.

GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)

Přidá dvojici klíč/hodnota do objektu ConcurrentDictionary<TKey,TValue> pomocí zadané funkce a argumentu, pokud klíč ještě neexistuje, nebo vrátí existující hodnotu, pokud klíč existuje.

Příklady

Následující příklad ukazuje, jak volat metodu GetOrAdd :

class CD_GetOrAddOrUpdate
{
    // Demonstrates:
    //      ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
    //      ConcurrentDictionary<TKey, TValue>.GetOrAdd()
    //      ConcurrentDictionary<TKey, TValue>[]
    static void Main()
    {
        // Construct a ConcurrentDictionary
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>();

        // Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
        Parallel.For(0, 10000, i =>
        {
            // Initial call will set cd[1] = 1.
            // Ensuing calls will set cd[1] = cd[1] + 1
            cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1);
        });

        Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]);

        // Should return 100, as key 2 is not yet in the dictionary
        int value = cd.GetOrAdd(2, (key) => 100);
        Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value);

        // Should return 100, as key 2 is already set to that value
        value = cd.GetOrAdd(2, 10000);
        Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value);
    }
}
// Demonstrates:
//      ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
//      ConcurrentDictionary<TKey, TValue>.GetOrAdd()
//      ConcurrentDictionary<TKey, TValue>[]

// Construct a ConcurrentDictionary
let cd = ConcurrentDictionary<int, int>()

// Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
Parallel.For(
    0,
    10000,
    fun i ->

        // Initial call will set cd[1] = 1.
        // Ensuing calls will set cd[1] = cd[1] + 1
        cd.AddOrUpdate(1, 1, (fun key oldValue -> oldValue + 1)) |> ignore
)
|> ignore

printfn $"After 10000 AddOrUpdates, cd[1] = {cd[1]}, should be 10000"

// Should return 100, as key 2 is not yet in the dictionary
let value = cd.GetOrAdd(2, (fun key -> 100))
printfn $"After initial GetOrAdd, cd[2] = {value} (should be 100)"

// Should return 100, as key 2 is already set to that value2
let value2 = cd.GetOrAdd(2, 10000)
printfn $"After second GetOrAdd, cd[2] = {value2} (should be 100)"
' Imports System.Collections.Concurrent
' Imports System.Threading.Tasks

Class CD_GetOrAddOrUpdate

    ' Demonstrates:
    ' ConcurrentDictionary<TKey, TValue>.AddOrUpdate()
    ' ConcurrentDictionary<TKey, TValue>.GetOrAdd()
    ' ConcurrentDictionary<TKey, TValue>[]
    Shared Sub Main()
        ' Construct a ConcurrentDictionary
        Dim cd As New ConcurrentDictionary(Of Integer, Integer)()

        ' Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates
        Parallel.For(0, 10000,
                       Sub(i)
                           ' Initial call will set cd[1] = 1. 
                           ' Ensuing calls will set cd[1] = cd[1] + 1
                           cd.AddOrUpdate(1, 1, Function(key, oldValue) oldValue + 1)
                       End Sub)

        Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd(1))

        ' Should return 100, as key 2 is not yet in the dictionary
        Dim value As Integer = cd.GetOrAdd(2, Function(key) 100)
        Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value)

        ' Should return 100, as key 2 is already set to that value
        value = cd.GetOrAdd(2, 10000)
        Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value)
    End Sub
End Class

GetOrAdd(TKey, Func<TKey,TValue>)

Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs

Pokud klíč ještě neexistuje, přidá dvojici klíč-hodnota do parametru ConcurrentDictionary<TKey,TValue> pomocí zadané funkce. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.

public:
 TValue GetOrAdd(TKey key, Func<TKey, TValue> ^ valueFactory);
public TValue GetOrAdd (TKey key, Func<TKey,TValue> valueFactory);
member this.GetOrAdd : 'Key * Func<'Key, 'Value> -> 'Value
Public Function GetOrAdd (key As TKey, valueFactory As Func(Of TKey, TValue)) As TValue

Parametry

key
TKey

Klíč elementu, který chcete přidat.

valueFactory
Func<TKey,TValue>

Funkce, která slouží k vygenerování hodnoty klíče.

Návraty

TValue

Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.

Výjimky

key nebo valueFactory je null.

Slovník obsahuje příliš mnoho prvků.

Poznámky

Pro úpravy a operace zápisu do slovníku ConcurrentDictionary<TKey,TValue> používá jemně odstupňované zamykání, které zajišťuje bezpečnost vláken. (Operace čtení ve slovníku se provádějí bez uzamčení.) Delegát je však volána mimo zámky, valueFactory aby se zabránilo problémům, které mohou nastat při spuštění neznámého kódu pod zámkem. GetOrAdd Proto není atomický, pokud jde o všechny ostatní operace ve ConcurrentDictionary<TKey,TValue> třídě.

Vzhledem k tomu, že klíč/hodnota může být vložen do jiného vlákna, zatímco valueFactory generuje hodnotu, nemůžete důvěřovat tomu, že jen proto, že valueFactory je spuštěn, bude jeho vytvořená hodnota vložena do slovníku a vrácena. Pokud voláte GetOrAdd současně v různých vláknech, valueFactory může být volána vícekrát, ale pouze jeden pár klíč/hodnota bude přidán do slovníku.

Vrácená hodnota závisí na přítomnosti klíče ve slovníku a na tom, jestli je klíč/hodnota vložena do jiného vlákna po GetOrAdd zavolání, ale před valueFactory vygenerováním hodnoty:

Scenario Vrácená hodnota
Klíč je již ve slovníku. Vrátí se existující hodnota.
Klíč není ve slovníku. valueFactory generuje hodnotu. Při opětovné kontrole klíče nebyl nalezen žádný klíč. Klíč/hodnota se vloží do slovníku a vrátí se hodnota.
Klíč není ve slovníku. valueFactory generuje hodnotu. Zatímco valueFactory generuje hodnotu, jiné vlákno vloží hodnotu klíče. Po valueFactory provedení a opětovné kontrole klíče se najde klíč vložený druhým vláknem. Vrátí se hodnota vložená druhým vláknem.

Viz také

Platí pro

GetOrAdd(TKey, TValue)

Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs

Pokud klíč ještě neexistuje, přidá do ConcurrentDictionary<TKey,TValue> páru klíč-hodnota. Vrátí novou hodnotu nebo existující hodnotu, pokud klíč existuje.

public:
 TValue GetOrAdd(TKey key, TValue value);
public TValue GetOrAdd (TKey key, TValue value);
member this.GetOrAdd : 'Key * 'Value -> 'Value
Public Function GetOrAdd (key As TKey, value As TValue) As TValue

Parametry

key
TKey

Klíč elementu, který chcete přidat.

value
TValue

Hodnota, která se má přidat, pokud klíč ještě neexistuje.

Návraty

TValue

Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.

Výjimky

key je null.

Slovník obsahuje příliš mnoho prvků.

Viz také

Platí pro

GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)

Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs
Zdroj:
ConcurrentDictionary.cs

Přidá dvojici klíč/hodnota do objektu ConcurrentDictionary<TKey,TValue> pomocí zadané funkce a argumentu, pokud klíč ještě neexistuje, nebo vrátí existující hodnotu, pokud klíč existuje.

public:
generic <typename TArg>
 TValue GetOrAdd(TKey key, Func<TKey, TArg, TValue> ^ valueFactory, TArg factoryArgument);
public TValue GetOrAdd<TArg> (TKey key, Func<TKey,TArg,TValue> valueFactory, TArg factoryArgument);
member this.GetOrAdd : 'Key * Func<'Key, 'Arg, 'Value> * 'Arg -> 'Value
Public Function GetOrAdd(Of TArg) (key As TKey, valueFactory As Func(Of TKey, TArg, TValue), factoryArgument As TArg) As TValue

Parametry typu

TArg

Typ argumentu, který se má předat do valueFactory.

Parametry

key
TKey

Klíč elementu, který chcete přidat.

valueFactory
Func<TKey,TArg,TValue>

Funkce, která slouží k vygenerování hodnoty klíče.

factoryArgument
TArg

Hodnota argumentu, která se má předat do valueFactory.

Návraty

TValue

Hodnota klíče. Bude to buď existující hodnota klíče, pokud je klíč již ve slovníku, nebo nová hodnota, pokud klíč nebyl ve slovníku.

Výjimky

keynull je odkaz (Nothing v jazyce Visual Basic).

Slovník obsahuje příliš mnoho prvků.

Poznámky

Pro úpravy a operace zápisu do slovníku ConcurrentDictionary<TKey,TValue> používá jemně odstupňované zamykání, které zajišťuje bezpečnost vláken. (Operace čtení ve slovníku se provádějí bez uzamčení.) Delegát je však volána mimo zámky, valueFactory aby se zabránilo problémům, které mohou nastat při spuštění neznámého kódu pod zámkem. GetOrAdd Proto není atomický, pokud jde o všechny ostatní operace ve ConcurrentDictionary<TKey,TValue> třídě.

Vzhledem k tomu, že klíč/hodnota může být vložen do jiného vlákna, zatímco valueFactory generuje hodnotu, nemůžete důvěřovat tomu, že jen proto, že valueFactory je spuštěn, bude jeho vytvořená hodnota vložena do slovníku a vrácena. Pokud voláte GetOrAdd současně v různých vláknech, valueFactory může být volána vícekrát, ale pouze jeden pár klíč/hodnota bude přidán do slovníku.

Vrácená hodnota závisí na přítomnosti klíče ve slovníku a na tom, jestli je klíč/hodnota vložena do jiného vlákna po GetOrAdd zavolání, ale před valueFactory vygenerováním hodnoty:

Scenario Vrácená hodnota
Klíč je již ve slovníku. Vrátí se existující hodnota.
Klíč není ve slovníku. valueFactory generuje hodnotu. Při opětovné kontrole klíče nebyl nalezen žádný klíč. Klíč/hodnota se vloží do slovníku a vrátí se hodnota.
Klíč není ve slovníku. valueFactory generuje hodnotu. Zatímco valueFactory generuje hodnotu, jiné vlákno vloží hodnotu klíče. Po valueFactory provedení a opětovné kontrole klíče se najde klíč vložený druhým vláknem. Vrátí se hodnota vložená druhým vláknem.

Platí pro