Compartir a través de


ConcurrentDictionary<TKey,TValue>.GetOrAdd Método

Definición

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe. Devuelve el nuevo valor, o el valor existente si ya existe la clave.

Sobrecargas

GetOrAdd(TKey, Func<TKey,TValue>)

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> utilizando la función especificada, si la clave no existe todavía. Devuelve el nuevo valor, o el valor existente si existe la clave.

GetOrAdd(TKey, TValue)

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe. Devuelve el nuevo valor, o el valor existente si existe la clave.

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

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> mediante la función especificada y un argumento si la clave aún no existe, o devuelve el valor existente si la clave ya existe.

Ejemplos

En el ejemplo siguiente se muestra cómo llamar al GetOrAdd método :

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

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> utilizando la función especificada, si la clave no existe todavía. Devuelve el nuevo valor, o el valor existente si existe la clave.

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

Parámetros

key
TKey

Clave del elemento que se va a agregar.

valueFactory
Func<TKey,TValue>

Función que se usa para generar un valor para la clave.

Devoluciones

TValue

Valor de la clave. Será el valor existente de la clave si esta ya existe en el diccionario o será un nuevo valor si la clave no está en el diccionario.

Excepciones

key o valueFactory es null.

El diccionario contiene demasiados elementos.

Comentarios

Para las modificaciones y las operaciones de escritura en el diccionario, ConcurrentDictionary<TKey,TValue> usa el bloqueo específico para garantizar la seguridad de los subprocesos. (Las operaciones de lectura en el diccionario se realizan de forma sin bloqueos). Sin embargo, se llama al valueFactory delegado fuera de los bloqueos para evitar los problemas que pueden surgir al ejecutar código desconocido bajo un bloqueo. Por lo tanto, GetOrAdd no es atómica con respecto a todas las demás operaciones de la ConcurrentDictionary<TKey,TValue> clase .

Dado que otro subproceso puede insertar una clave/valor mientras valueFactory genera un valor, no se puede confiar en que solo se valueFactory ejecute, su valor generado se insertará en el diccionario y se devolverá. Si llama GetOrAdd simultáneamente a en subprocesos diferentes, valueFactory se puede llamar varias veces, pero solo se agregará un par clave-valor al diccionario.

El valor devuelto depende de la presencia de la clave en el diccionario y de si otro subproceso inserta una clave o valor después de GetOrAdd llamar a , pero antes valueFactory de generar un valor:

Escenario Valor devuelto
La clave ya está en el diccionario. Se devuelve el valor existente.
La clave no está en el diccionario. valueFactory genera un valor. Al volver a comprobar la clave, no se encuentra ninguna clave. La clave/valor se inserta en el diccionario y se devuelve el valor .
La clave no está en el diccionario. valueFactory genera un valor. Mientras valueFactory se genera el valor, un subproceso diferente inserta un valor para la clave. Después valueFactory de ejecutar y al volver a comprobar la clave, se encuentra la clave insertada por el otro subproceso. Se devuelve el valor insertado por el otro subproceso.

Consulte también

Se aplica a

GetOrAdd(TKey, TValue)

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

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe. Devuelve el nuevo valor, o el valor existente si existe la clave.

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

Parámetros

key
TKey

Clave del elemento que se va a agregar.

value
TValue

Valor que se va a agregar si la clave aún no existe.

Devoluciones

TValue

Valor de la clave. Será el valor existente de la clave si esta ya existe en el diccionario o será un nuevo valor si la clave no está en el diccionario.

Excepciones

key es null.

El diccionario contiene demasiados elementos.

Consulte también

Se aplica a

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

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

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> mediante la función especificada y un argumento si la clave aún no existe, o devuelve el valor existente si la clave ya 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

Parámetros de tipo

TArg

Tipo de un argumento que se va a pasar a valueFactory.

Parámetros

key
TKey

Clave del elemento que se va a agregar.

valueFactory
Func<TKey,TArg,TValue>

Función que se usa para generar un valor para la clave.

factoryArgument
TArg

Valor de argumento que se pasará a valueFactory.

Devoluciones

TValue

Valor de la clave. Será el valor existente de la clave si esta ya existe en el diccionario o será un nuevo valor si la clave no está en el diccionario.

Excepciones

key es una referencia null (Nothing en Visual Basic).

El diccionario contiene demasiados elementos.

Comentarios

Para las modificaciones y las operaciones de escritura en el diccionario, ConcurrentDictionary<TKey,TValue> usa el bloqueo específico para garantizar la seguridad de los subprocesos. (Las operaciones de lectura en el diccionario se realizan de forma sin bloqueos). Sin embargo, se llama al valueFactory delegado fuera de los bloqueos para evitar los problemas que pueden surgir al ejecutar código desconocido bajo un bloqueo. Por lo tanto, GetOrAdd no es atómica con respecto a todas las demás operaciones de la ConcurrentDictionary<TKey,TValue> clase .

Dado que otro subproceso puede insertar una clave/valor mientras valueFactory genera un valor, no se puede confiar en que solo se valueFactory ejecute, su valor generado se insertará en el diccionario y se devolverá. Si llama GetOrAdd simultáneamente a en subprocesos diferentes, valueFactory se puede llamar varias veces, pero solo se agregará un par clave-valor al diccionario.

El valor devuelto depende de la presencia de la clave en el diccionario y de si otro subproceso inserta una clave o valor después de GetOrAdd llamar a , pero antes valueFactory de generar un valor:

Escenario Valor devuelto
La clave ya está en el diccionario. Se devuelve el valor existente.
La clave no está en el diccionario. valueFactory genera un valor. Al volver a comprobar la clave, no se encuentra ninguna clave. La clave/valor se inserta en el diccionario y se devuelve el valor .
La clave no está en el diccionario. valueFactory genera un valor. Mientras valueFactory se genera el valor, un subproceso diferente inserta un valor para la clave. Después valueFactory de ejecutar y al volver a comprobar la clave, se encuentra la clave insertada por el otro subproceso. Se devuelve el valor insertado por el otro subproceso.

Se aplica a