Freigeben über


ConcurrentDictionary<TKey,TValue>.GetOrAdd Methode

Definition

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel nicht bereits vorhanden ist. Gibt den neuen Wert oder den vorhandenen Wert zurück, wenn der Schlüssel bereits existiert.

Überlädt

GetOrAdd(TKey, Func<TKey,TValue>)

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel/Wert-Paar mithilfe der angegebenen Funktion hinzu, wenn der Schlüssel noch nicht vorhanden ist. Gibt den neuen Wert oder den vorhandenen Wert zurück, wenn der Schlüssel existiert.

GetOrAdd(TKey, TValue)

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel nicht bereits vorhanden ist. Gibt den neuen Wert oder den vorhandenen Wert zurück, wenn der Schlüssel existiert.

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

Fügt dem ConcurrentDictionary<TKey,TValue> mithilfe der angegebenen Funktion und eines Arguments ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel noch nicht vorhanden ist, oder gibt den vorhanden Wert zurück, wenn der Schlüssel vorhanden ist.

Beispiele

Im folgenden Beispiel wird gezeigt, wie die GetOrAdd -Methode aufgerufen wird:

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

Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel/Wert-Paar mithilfe der angegebenen Funktion hinzu, wenn der Schlüssel noch nicht vorhanden ist. Gibt den neuen Wert oder den vorhandenen Wert zurück, wenn der Schlüssel existiert.

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

Parameter

key
TKey

Der Schlüssel des hinzuzufügenden Elements.

valueFactory
Func<TKey,TValue>

Die Funktion, mit der ein Wert für den Schlüssel generiert wird.

Gibt zurück

TValue

Der Wert für den Schlüssel. Dies ist entweder der vorhandene Wert für den Schlüssel, wenn der Schlüssel bereits im Wörterbuch vorhanden ist, oder der neue Wert, wenn der Schlüssel nicht im Wörterbuch vorhanden war.

Ausnahmen

key oder valueFactory ist null.

Das Wörterbuch enthält zu viele Elemente.

Hinweise

Für Änderungen und Schreibvorgänge am Wörterbuch wird eine differenzierte Sperrung verwendet, ConcurrentDictionary<TKey,TValue> um die Threadsicherheit zu gewährleisten. (Lesevorgänge für das Wörterbuch werden sperrfrei ausgeführt.) Der Delegat wird jedoch außerhalb der Sperren aufgerufen, valueFactory um probleme zu vermeiden, die beim Ausführen von unbekanntem Code unter einer Sperre auftreten können. GetOrAdd Daher ist in Bezug auf alle anderen Operationen auf der ConcurrentDictionary<TKey,TValue> Klasse nicht unteilbar.

Da ein Schlüssel/Wert von einem anderen Thread eingefügt werden kann, während valueFactory ein Wert generiert wird, können Sie nicht darauf vertrauen, dass der erzeugte Wert nur aufgrund valueFactory der Ausführung in das Wörterbuch eingefügt und zurückgegeben wird. Wenn Sie gleichzeitig für verschiedene Threads aufrufen GetOrAdd , valueFactory kann mehrmals aufgerufen werden, aber nur ein Schlüssel-Wert-Paar wird dem Wörterbuch hinzugefügt.

Der Rückgabewert hängt davon ab, ob der Schlüssel im Wörterbuch vorhanden ist und ob ein Schlüssel/Wert von einem anderen Thread eingefügt wird, nachdem GetOrAdd aufgerufen wird, aber bevor valueFactory ein Wert generiert wird:

Szenario Rückgabewert
Der Schlüssel ist bereits im Wörterbuch enthalten. Der vorhandene Wert wird zurückgegeben.
Der Schlüssel befindet sich nicht im Wörterbuch. valueFactory generiert einen Wert. Beim erneuten Überprüfen des Schlüssels wird kein Schlüssel gefunden. Der Schlüssel/Wert wird in das Wörterbuch eingefügt, und der Wert wird zurückgegeben.
Der Schlüssel befindet sich nicht im Wörterbuch. valueFactory generiert einen Wert. Während valueFactory der Generierung des Werts fügt ein anderer Thread einen Wert für den Schlüssel ein. Nach der valueFactory Ausführung und beim erneuten Überprüfen des Schlüssels wird der schlüssel gefunden, der vom anderen Thread eingefügt wurde. Der vom anderen Thread eingefügte Wert wird zurückgegeben.

Weitere Informationen

Gilt für:

GetOrAdd(TKey, TValue)

Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel nicht bereits vorhanden ist. Gibt den neuen Wert oder den vorhandenen Wert zurück, wenn der Schlüssel existiert.

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

Parameter

key
TKey

Der Schlüssel des hinzuzufügenden Elements.

value
TValue

Der hinzuzufügende Wert, wenn der Schlüssel nicht bereits vorhanden ist.

Gibt zurück

TValue

Der Wert für den Schlüssel. Dies ist entweder der vorhandene Wert für den Schlüssel, wenn der Schlüssel bereits im Wörterbuch vorhanden ist, oder der neue Wert, wenn der Schlüssel nicht im Wörterbuch vorhanden war.

Ausnahmen

key ist null.

Das Wörterbuch enthält zu viele Elemente.

Weitere Informationen

Gilt für:

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

Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs
Quelle:
ConcurrentDictionary.cs

Fügt dem ConcurrentDictionary<TKey,TValue> mithilfe der angegebenen Funktion und eines Arguments ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel noch nicht vorhanden ist, oder gibt den vorhanden Wert zurück, wenn der Schlüssel vorhanden ist.

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

Typparameter

TArg

Der Typ eines Arguments, das an übergeben werden valueFactorysoll.

Parameter

key
TKey

Der Schlüssel des hinzuzufügenden Elements.

valueFactory
Func<TKey,TArg,TValue>

Die Funktion, mit der ein Wert für den Schlüssel generiert wird.

factoryArgument
TArg

Ein Argumentwert, der an valueFactory übergeben werden soll.

Gibt zurück

TValue

Der Wert für den Schlüssel. Dies ist entweder der vorhandene Wert für den Schlüssel, wenn der Schlüssel bereits im Wörterbuch vorhanden ist, oder der neue Wert, wenn der Schlüssel nicht im Wörterbuch vorhanden war.

Ausnahmen

key ist ein null-Verweis („Nothing“ in Visual Basic).

Das Wörterbuch enthält zu viele Elemente.

Hinweise

Für Änderungen und Schreibvorgänge am Wörterbuch wird eine differenzierte Sperrung verwendet, ConcurrentDictionary<TKey,TValue> um die Threadsicherheit zu gewährleisten. (Lesevorgänge für das Wörterbuch werden sperrfrei ausgeführt.) Der Delegat wird jedoch außerhalb der Sperren aufgerufen, valueFactory um probleme zu vermeiden, die beim Ausführen von unbekanntem Code unter einer Sperre auftreten können. GetOrAdd Daher ist in Bezug auf alle anderen Operationen auf der ConcurrentDictionary<TKey,TValue> Klasse nicht unteilbar.

Da ein Schlüssel/Wert von einem anderen Thread eingefügt werden kann, während valueFactory ein Wert generiert wird, können Sie nicht darauf vertrauen, dass der erzeugte Wert nur aufgrund valueFactory der Ausführung in das Wörterbuch eingefügt und zurückgegeben wird. Wenn Sie gleichzeitig für verschiedene Threads aufrufen GetOrAdd , valueFactory kann mehrmals aufgerufen werden, aber nur ein Schlüssel-Wert-Paar wird dem Wörterbuch hinzugefügt.

Der Rückgabewert hängt davon ab, ob der Schlüssel im Wörterbuch vorhanden ist und ob ein Schlüssel/Wert von einem anderen Thread eingefügt wird, nachdem GetOrAdd aufgerufen wird, aber bevor valueFactory ein Wert generiert wird:

Szenario Rückgabewert
Der Schlüssel ist bereits im Wörterbuch enthalten. Der vorhandene Wert wird zurückgegeben.
Der Schlüssel befindet sich nicht im Wörterbuch. valueFactory generiert einen Wert. Beim erneuten Überprüfen des Schlüssels wird kein Schlüssel gefunden. Der Schlüssel/Wert wird in das Wörterbuch eingefügt, und der Wert wird zurückgegeben.
Der Schlüssel befindet sich nicht im Wörterbuch. valueFactory generiert einen Wert. Während valueFactory der Generierung des Werts fügt ein anderer Thread einen Wert für den Schlüssel ein. Nach der valueFactory Ausführung und beim erneuten Überprüfen des Schlüssels wird der schlüssel gefunden, der vom anderen Thread eingefügt wurde. Der vom anderen Thread eingefügte Wert wird zurückgegeben.

Gilt für: