Freigeben über


ConcurrentDictionary<TKey,TValue>.AddOrUpdate Methode

Definition

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel nicht bereits vorhanden ist, oder aktualisiert ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue>, wenn der Schlüssel bereits vorhanden ist.

Überlädt

AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

Verwendet die angegebene Funktionen, um dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzuzufügen, wenn der Schlüssel nicht bereits vorhanden ist, oder um ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> zu aktualisieren, wenn der Schlüssel bereits vorhanden ist.

AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)

Fügt dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzu, wenn der Schlüssel nicht bereits vorhanden ist, oder aktualisiert ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> mithilfe der angegebenen Funktion, wenn der Schlüssel bereits vorhanden ist.

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

Verwendet die angegebene Funktionen und das angegebene Argument, um dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzuzufügen, wenn der Schlüssel nicht bereits vorhanden ist, oder um ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> zu aktualisieren, wenn der Schlüssel bereits vorhanden ist.

Beispiele

Im folgenden Beispiel wird gezeigt, wie die AddOrUpdate -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

AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

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

Verwendet die angegebene Funktionen, um dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzuzufügen, wenn der Schlüssel nicht bereits vorhanden ist, oder um ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> zu aktualisieren, wenn der Schlüssel bereits vorhanden ist.

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

Parameter

key
TKey

Der Schlüssel, der hinzugefügt oder dessen Wert aktualisiert werden soll.

addValueFactory
Func<TKey,TValue>

Die Funktion zum Generieren eines Werts für einen nicht vorhandenen Schlüssel.

updateValueFactory
Func<TKey,TValue,TValue>

Die Funktion zum Generieren eines neuen Werts für einen vorhandenen Schlüssel auf Grundlage des vorhandenen Werts des Schlüssels.

Gibt zurück

TValue

Der neue Wert für den Schlüssel. Dies ist entweder das Ergebnis von addValueFactory (wenn der Schlüssel nicht vorhanden war) oder das Ergebnis von updateValueFactory (wenn der Schlüssel vorhanden war).

Ausnahmen

key, addValueFactory oder updateValueFactory ist null.

Das Wörterbuch enthält zu viele Elemente.

Hinweise

Wenn Sie gleichzeitig in verschiedenen Threads aufrufen AddOrUpdate , addValueFactory kann mehrmals aufgerufen werden, aber das Schlüssel-Wert-Paar wird möglicherweise nicht für jeden Aufruf zum Wörterbuch hinzugefügt.

Für Änderungen und Schreibvorgänge am Wörterbuch verwendet eine differenzierte Sperrung, ConcurrentDictionary<TKey,TValue> um die Threadsicherheit zu gewährleisten (Lesevorgänge für das Wörterbuch werden auf eine sperrfreie Weise ausgeführt). Die addValueFactory Delegaten und updateValueFactory können mehrmals ausgeführt werden, um zu überprüfen, ob der Wert wie erwartet hinzugefügt oder aktualisiert wurde. Sie werden jedoch außerhalb der Sperren aufgerufen, um die Probleme zu vermeiden, die beim Ausführen von unbekanntem Code unter einer Sperre auftreten können. AddOrUpdate Daher ist in Bezug auf alle anderen Operationen auf der ConcurrentDictionary<TKey,TValue> Klasse nicht unteilbar.

Weitere Informationen

Gilt für:

AddOrUpdate(TKey, TValue, Func<TKey,TValue,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, oder aktualisiert ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> mithilfe der angegebenen Funktion, wenn der Schlüssel bereits vorhanden ist.

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

Parameter

key
TKey

Der Schlüssel, der hinzugefügt oder dessen Wert aktualisiert werden soll.

addValue
TValue

Der Wert, der für einen fehlenden Schlüssel hinzugefügt werden soll.

updateValueFactory
Func<TKey,TValue,TValue>

Die Funktion zum Generieren eines neuen Werts für einen vorhandenen Schlüssel auf Grundlage des vorhandenen Werts des Schlüssels.

Gibt zurück

TValue

Der neue Wert für den Schlüssel. Dies ist entweder addValue (wenn der Schlüssel nicht vorhanden war) oder das Ergebnis von updateValueFactory (wenn der Schlüssel vorhanden war).

Ausnahmen

key oder updateValueFactory ist null.

Das Wörterbuch enthält zu viele Elemente.

Beispiele

Im folgenden Codebeispiel wird gezeigt, wie ein ConcurrentDictionary<TKey,TValue> initialisiert wird und wie die AddOrUpdate-Methode verwendet wird, um der Auflistung ein zusätzliches Element hinzuzufügen und die vorhandenen Elemente zu aktualisieren.

using System;
using System.Collections.Concurrent;

class CD_Ctor
{
    // Demonstrates:
    //      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
    //      ConcurrentDictionary<TKey, TValue>[TKey]
    static void Main()
    {
        // We know how many items we want to insert into the ConcurrentDictionary.
        // So set the initial capacity to some prime number above that, to ensure that
        // the ConcurrentDictionary does not need to be resized while initializing it.
        int HIGHNUMBER = 64;
        int initialCapacity = 101;

        // The higher the concurrencyLevel, the higher the theoretical number of operations
        // that could be performed concurrently on the ConcurrentDictionary.  However, global
        // operations like resizing the dictionary take longer as the concurrencyLevel rises.
        // For the purposes of this example, we'll compromise at numCores * 2.
        int numProcs = Environment.ProcessorCount;
        int concurrencyLevel = numProcs * 2;

        // Construct the dictionary with the desired concurrencyLevel and initialCapacity
        ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity);

        // Initialize the dictionary
        for (int i = 1; i <= HIGHNUMBER; i++) cd[i] = i * i;

        Console.WriteLine("The square of 23 is {0} (should be {1})", cd[23], 23 * 23);

        // Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their
        // key  and a new item will be added that is the square of its key.
        for (int i = 1; i <= HIGHNUMBER + 1; i++)
          cd.AddOrUpdate(i, i * i, (k,v) => v / i);

        Console.WriteLine("The square root of 529 is {0} (should be {1})", cd[23], 529 / 23);
        Console.WriteLine("The square of 65 is {0} (should be {1})", cd[HIGHNUMBER + 1], ((HIGHNUMBER + 1) * (HIGHNUMBER + 1)));
    }
}
open System
open System.Collections.Concurrent

// Demonstrates:
//      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity)
//      ConcurrentDictionary<TKey, TValue>[TKey]

// We know how many items we want to insert into the ConcurrentDictionary.
// So set the initial capacity to some prime number above that, to ensure that
// the ConcurrentDictionary does not need to be resized while initializing it.
let HIGHNUMBER = 64
let initialCapacity = 101

// The higher the concurrencyLevel, the higher the theoretical number of operations
// that could be performed concurrently on the ConcurrentDictionary.  However, global
// operations like resizing the dictionary take longer as the concurrencyLevel rises.
// For the purposes of this example, we'll compromise at numCores * 2.
let numProcs = Environment.ProcessorCount
let concurrencyLevel = numProcs * 2

// Construct the dictionary with the desired concurrencyLevel and initialCapacity
let cd = ConcurrentDictionary<int, int>(concurrencyLevel, initialCapacity)

// Initialize the dictionary
for i = 1 to HIGHNUMBER do
    cd[i] <- i * i

printfn $"The square of 23 is {cd[23]} (should be {23 * 23})"

// Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their
// key  and a new item will be added that is the square of its key.
for i = 1 to HIGHNUMBER + 1 do
    cd.AddOrUpdate(i, i * i, (fun k v -> v / i)) |> ignore

printfn $"The square root of 529 is {cd[23]} (should be {529 / 23})"
printfn $"The square of 65 is {cd[HIGHNUMBER + 1]} (should be {(HIGHNUMBER + 1) * (HIGHNUMBER + 1)})"
Imports System.Collections.Concurrent

Class CD_Ctor
    ' Demonstrates: 
    '      ConcurrentDictionary<TKey, TValue> ctor(concurrencyLevel, initialCapacity) 
    '      ConcurrentDictionary<TKey, TValue>[TKey] 
    Public Shared Sub Main()
        ' We know how many items we want to insert into the ConcurrentDictionary. 
        ' So set the initial capacity to some prime number above that, to ensure that 
        ' the ConcurrentDictionary does not need to be resized while initializing it. 
        Dim HIGHNUMBER As Integer = 64
        Dim initialCapacity As Integer = 101

        ' The higher the concurrencyLevel, the higher the theoretical number of operations 
        ' that could be performed concurrently on the ConcurrentDictionary.  However, global 
        ' operations like resizing the dictionary take longer as the concurrencyLevel rises.  
        ' For the purposes of this example, we'll compromise at numCores * 2. 
        Dim numProcs As Integer = Environment.ProcessorCount
        Dim concurrencyLevel As Integer = numProcs * 2

        ' Construct the dictionary with the desired concurrencyLevel and initialCapacity
        Dim cd As New ConcurrentDictionary(Of Integer, Integer)(concurrencyLevel, initialCapacity)

        ' Initialize the dictionary 
        For i As Integer = 1 To HIGHNUMBER
            cd(i) = i * i
        Next

        Console.WriteLine("The square of 23 is {0} (should be {1})", cd(23), 23 * 23)

        ' Now iterate through, adding one to the end of the list. Existing items should be updated to be divided by their 
        ' key  and a new item will be added that is the square of its key.
        For i As Integer = 1 To HIGHNUMBER + 1

            cd.AddOrUpdate(i, i * i, Function(k, v)
                                         Return v / i
                                     End Function)
        Next

        Console.WriteLine("The square root of 529 is {0} (should be {1})", cd(23), 529 / 23)
        Console.WriteLine("The square of 65 is {0} (should be {1})", cd(HIGHNUMBER + 1), ((HIGHNUMBER + 1) * (HIGHNUMBER + 1)))

    End Sub
End Class

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.) Die addValueFactory Delegaten und updateValueFactory können mehrmals ausgeführt werden, um zu überprüfen, ob der Wert wie erwartet hinzugefügt oder aktualisiert wurde. Sie werden jedoch außerhalb der Sperren aufgerufen, um die Probleme zu vermeiden, die beim Ausführen von unbekanntem Code unter einer Sperre auftreten können. AddOrUpdate Daher ist in Bezug auf alle anderen Operationen auf der ConcurrentDictionary<TKey,TValue> Klasse nicht unteilbar.

Weitere Informationen

Gilt für:

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

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

Verwendet die angegebene Funktionen und das angegebene Argument, um dem ConcurrentDictionary<TKey,TValue> ein Schlüssel-Wert-Paar hinzuzufügen, wenn der Schlüssel nicht bereits vorhanden ist, oder um ein Schlüssel-Wert-Paar im ConcurrentDictionary<TKey,TValue> zu aktualisieren, wenn der Schlüssel bereits vorhanden ist.

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

Typparameter

TArg

Der Typ eines Arguments, das an addValueFactory und updateValueFactoryübergeben werden soll.

Parameter

key
TKey

Der Schlüssel, der hinzugefügt oder dessen Wert aktualisiert werden soll.

addValueFactory
Func<TKey,TArg,TValue>

Die Funktion zum Generieren eines Werts für einen nicht vorhandenen Schlüssel.

updateValueFactory
Func<TKey,TValue,TArg,TValue>

Die Funktion zum Generieren eines neuen Werts für einen vorhandenen Schlüssel auf Grundlage des vorhandenen Werts des Schlüssels.

factoryArgument
TArg

Ein Argument, das an addValueFactory und updateValueFactory übergeben werden soll.

Gibt zurück

TValue

Der neue Wert für den Schlüssel. Dies ist entweder das Ergebnis von addValueFactory (wenn der Schlüssel nicht vorhanden war) oder das Ergebnis von updateValueFactory (wenn der Schlüssel vorhanden war).

Ausnahmen

key, addValueFactory oder updateValueFactory ist ein NULL-Verweis („Nothing“ in Visual Basic).

Das Wörterbuch enthält zu viele Elemente.

Hinweise

Wenn Sie gleichzeitig in verschiedenen Threads aufrufen AddOrUpdate , addValueFactory kann mehrmals aufgerufen werden, aber das Schlüssel-Wert-Paar wird möglicherweise nicht für jeden Aufruf zum Wörterbuch hinzugefügt.

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.) Die addValueFactory Delegaten und updateValueFactory können mehrmals ausgeführt werden, um zu überprüfen, ob der Wert wie erwartet hinzugefügt oder aktualisiert wurde. Sie werden jedoch außerhalb der Sperren aufgerufen, um die Probleme zu vermeiden, die beim Ausführen von unbekanntem Code unter einer Sperre auftreten können. AddOrUpdate Daher ist in Bezug auf alle anderen Operationen auf der ConcurrentDictionary<TKey,TValue> Klasse nicht unteilbar.

Gilt für: