Partager via


ConcurrentDictionary<TKey,TValue>.GetOrAdd Méthode

Définition

Ajoute une paire clé/valeur au ConcurrentDictionary<TKey,TValue> si la clé n'existe pas déjà. Retourne la nouvelle valeur ou la valeur existante si la clé existe déjà.

Surcharges

GetOrAdd(TKey, Func<TKey,TValue>)

Ajoute une paire clé/valeur à ConcurrentDictionary<TKey,TValue> en utilisant la fonction spécifiée, si la clé n'existe pas. Retourne la nouvelle valeur ou la valeur existante si la clé existe.

GetOrAdd(TKey, TValue)

Ajoute une paire clé/valeur au ConcurrentDictionary<TKey,TValue> si la clé n'existe pas déjà. Retourne la nouvelle valeur ou la valeur existante si la clé existe.

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

Ajoute une paire clé/valeur au ConcurrentDictionary<TKey,TValue> en utilisant la fonction spécifiée et un argument si la clé n’existe pas déjà, ou retourne la valeur existante si la clé existe.

Exemples

L’exemple suivant montre comment appeler la GetOrAdd méthode :

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

Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs

Ajoute une paire clé/valeur à ConcurrentDictionary<TKey,TValue> en utilisant la fonction spécifiée, si la clé n'existe pas. Retourne la nouvelle valeur ou la valeur existante si la clé existe.

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

Paramètres

key
TKey

Clé de l'élément à ajouter.

valueFactory
Func<TKey,TValue>

Fonction utilisée pour générer une valeur pour la clé.

Retours

TValue

Valeur pour la clé. Il s'agit de la valeur existante pour la clé si la clé est déjà dans le dictionnaire, ou de la nouvelle valeur si la clé n'était pas dans le dictionnaire.

Exceptions

key ou valueFactory est null.

Le dictionnaire contient trop d’éléments.

Remarques

Pour les modifications et les opérations d’écriture dans le dictionnaire, ConcurrentDictionary<TKey,TValue> utilise un verrouillage affiné pour garantir la sécurité des threads. (Les opérations de lecture sur le dictionnaire sont effectuées sans verrou.) Toutefois, le valueFactory délégué est appelé en dehors des verrous pour éviter les problèmes qui peuvent survenir lors de l’exécution de code inconnu sous un verrou. Par conséquent, GetOrAdd n’est pas atomique en ce qui concerne toutes les autres opérations sur la ConcurrentDictionary<TKey,TValue> classe .

Étant donné qu’une clé/valeur peut être insérée par un autre thread lors valueFactory de la génération d’une valeur, vous ne pouvez pas faire confiance à ce que valueFactory sa valeur produite soit insérée dans le dictionnaire et retournée. Si vous appelez GetOrAdd simultanément sur différents threads, valueFactory peut être appelé plusieurs fois, mais une seule paire clé/valeur sera ajoutée au dictionnaire.

La valeur de retour dépend de la présence de la clé dans le dictionnaire et si une clé/valeur est insérée par un autre thread après GetOrAdd est appelé, mais avant valueFactory génère une valeur :

Scénario Valeur retournée
La clé se trouve déjà dans le dictionnaire. La valeur existante est retournée.
La clé n’est pas dans le dictionnaire. valueFactory génère une valeur. Lors de la nouvelle vérification de la clé, aucune clé n’est trouvée. La clé/valeur est insérée dans le dictionnaire et la valeur est retournée.
La clé n’est pas dans le dictionnaire. valueFactory génère une valeur. Lors valueFactory de la génération de la valeur, un thread différent insère une valeur pour la clé. Après valueFactory l’exécution et lors de la revérification de la clé, la clé insérée par l’autre thread est trouvée. La valeur insérée par l’autre thread est retournée.

Voir aussi

S’applique à

GetOrAdd(TKey, TValue)

Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs

Ajoute une paire clé/valeur au ConcurrentDictionary<TKey,TValue> si la clé n'existe pas déjà. Retourne la nouvelle valeur ou la valeur existante si la clé existe.

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

Paramètres

key
TKey

Clé de l'élément à ajouter.

value
TValue

Valeur à ajouter, si la clé n’existe pas encore.

Retours

TValue

Valeur pour la clé. Il s'agit de la valeur existante pour la clé si la clé est déjà dans le dictionnaire, ou de la nouvelle valeur si la clé n'était pas dans le dictionnaire.

Exceptions

key a la valeur null.

Le dictionnaire contient trop d’éléments.

Voir aussi

S’applique à

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

Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs
Source:
ConcurrentDictionary.cs

Ajoute une paire clé/valeur au ConcurrentDictionary<TKey,TValue> en utilisant la fonction spécifiée et un argument si la clé n’existe pas déjà, ou retourne la valeur existante si la clé existe.

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

Paramètres de type

TArg

Type d’un argument à passer dans valueFactory.

Paramètres

key
TKey

Clé de l'élément à ajouter.

valueFactory
Func<TKey,TArg,TValue>

Fonction utilisée pour générer une valeur pour la clé.

factoryArgument
TArg

Valeur d’argument à passer dans valueFactory.

Retours

TValue

Valeur pour la clé. Il s'agit de la valeur existante pour la clé si la clé est déjà dans le dictionnaire, ou de la nouvelle valeur si la clé n'était pas dans le dictionnaire.

Exceptions

key est une référence null (Nothing en Visual Basic).

Le dictionnaire contient trop d’éléments.

Remarques

Pour les modifications et les opérations d’écriture dans le dictionnaire, ConcurrentDictionary<TKey,TValue> utilise un verrouillage affiné pour garantir la sécurité des threads. (Les opérations de lecture sur le dictionnaire sont effectuées sans verrou.) Toutefois, le valueFactory délégué est appelé en dehors des verrous pour éviter les problèmes qui peuvent survenir lors de l’exécution de code inconnu sous un verrou. Par conséquent, GetOrAdd n’est pas atomique en ce qui concerne toutes les autres opérations sur la ConcurrentDictionary<TKey,TValue> classe .

Étant donné qu’une clé/valeur peut être insérée par un autre thread lors valueFactory de la génération d’une valeur, vous ne pouvez pas faire confiance à ce que valueFactory sa valeur produite soit insérée dans le dictionnaire et retournée. Si vous appelez GetOrAdd simultanément sur différents threads, valueFactory peut être appelé plusieurs fois, mais une seule paire clé/valeur sera ajoutée au dictionnaire.

La valeur de retour dépend de la présence de la clé dans le dictionnaire et si une clé/valeur est insérée par un autre thread après GetOrAdd est appelé, mais avant valueFactory génère une valeur :

Scénario Valeur retournée
La clé se trouve déjà dans le dictionnaire. La valeur existante est retournée.
La clé n’est pas dans le dictionnaire. valueFactory génère une valeur. Lors de la nouvelle vérification de la clé, aucune clé n’est trouvée. La clé/valeur est insérée dans le dictionnaire et la valeur est retournée.
La clé n’est pas dans le dictionnaire. valueFactory génère une valeur. Lors valueFactory de la génération de la valeur, un thread différent insère une valeur pour la clé. Après valueFactory l’exécution et lors de la revérification de la clé, la clé insérée par l’autre thread est trouvée. La valeur insérée par l’autre thread est retournée.

S’applique à