ConcurrentDictionary<TKey,TValue>.GetOrAdd Método

Definición

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Devuelve el nuevo valor, o el valor existente si ya existe la clave.Returns the new value, or the existing value if the key already exists.

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.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Devuelve el nuevo valor, o el valor existente si existe la clave.Returns the new value, or the existing value if the key exists.

GetOrAdd(TKey, TValue)

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Devuelve el nuevo valor, o el valor existente si existe la clave.Returns the new value, or the existing value if the key exists.

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.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function and an argument if the key does not already exist, or returns the existing value if the key exists.

Ejemplos

En el ejemplo siguiente se muestra cómo llamar GetOrAdd al método:The following example shows how to call the GetOrAdd method:

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);
    }
}
' 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>)

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> utilizando la función especificada, si la clave no existe todavía.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Devuelve el nuevo valor, o el valor existente si existe la clave.Returns the new value, or the existing value if the key exists.

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.The key of the element to add.

valueFactory
Func<TKey,TValue>

Función que se usa para generar un valor para la clave.The function used to generate a value for the key.

Devoluciones

TValue

Valor de la clave.The value for the key. 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.This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary.

Excepciones

key o valueFactory es null.key or valueFactory is null.

El diccionario ya contiene el número máximo de elementos (MaxValue).The dictionary already contains the maximum number of elements (MaxValue).

Comentarios

En el caso de las modificaciones y las operaciones ConcurrentDictionary<TKey,TValue> de escritura en el diccionario, usa un bloqueo preciso para garantizar la seguridad para subprocesos.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (Las operaciones de lectura en el diccionario se realizan sin bloqueos). Sin embargo, valueFactory se llama al delegado fuera de los bloqueos para evitar los problemas que pueden surgir al ejecutar código desconocido en un bloqueo.(Read operations on the dictionary are performed in a lock-free manner.) However, the valueFactory delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Por lo GetOrAdd tanto, no es atómico con respecto a todas las demás ConcurrentDictionary<TKey,TValue> operaciones en la clase.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Puesto que un subproceso puede insertar un valor o clave, valueFactory mientras se genera un valor, no puede confiar en que valueFactory , simplemente porque se ejecuta, su valor generado se insertará en el Diccionario y se devolverá.Since a key/value can be inserted by another thread while valueFactory is generating a value, you cannot trust that just because valueFactory executed, its produced value will be inserted into the dictionary and returned. Si llama GetOrAdd a simultáneamente en diferentes subprocesos, valueFactory se puede llamar varias veces a, pero solo se agregará un par clave-valor al diccionario.If you call GetOrAdd simultaneously on different threads, valueFactory may be called multiple times, but only one key/value pair will be added to the dictionary.

El valor devuelto depende de la presencia de la clave en el Diccionario y de si un subproceso inserta una clave o un GetOrAdd valor después de que valueFactory se llame a, pero antes de que genere un valor:The return value depends on the presence of the key in the dictionary and whether a key/value is inserted by another thread after GetOrAdd is called but before valueFactory generates a value:

EscenarioScenario Valor devueltoReturn value
La clave ya está en el diccionario.The key is already in the dictionary. Se devuelve el valor existente.The existing value is returned.
La clave no está en el diccionario.The key is not in the dictionary. valueFactorygenera un valor.valueFactory generates a value. Al volver a comprobar la clave, no se encuentra ninguna clave.On rechecking for the key, no key is found. La clave/valor se inserta en el Diccionario y se devuelve el valor.The key/value is inserted into the dictionary, and the value is returned.
La clave no está en el diccionario.The key is not in the dictionary. valueFactorygenera un valor.valueFactory generates a value. Mientras valueFactory genera el valor, otro subproceso inserta un valor para la clave.While valueFactory is generating the value, a different thread inserts a value for the key. Después valueFactory de que se ejecute y al volver a comprobar la clave, se encuentra la clave insertada por el otro subproceso.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. Se devuelve el valor insertado por el otro subproceso.The value inserted by the other thread is returned.

Consulte también:

GetOrAdd(TKey, TValue)

Agrega un par clave-valor a ConcurrentDictionary<TKey,TValue> si la clave no existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Devuelve el nuevo valor, o el valor existente si existe la clave.Returns the new value, or the existing value if the key exists.

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.The key of the element to add.

value
TValue

Valor que se va a agregar si la clave aún no existe.The value to be added, if the key does not already exist.

Devoluciones

TValue

Valor de la clave.The value for the key. 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.This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary.

Excepciones

key es null.key is null.

El diccionario ya contiene el número máximo de elementos (MaxValue).The dictionary already contains the maximum number of elements (MaxValue).

Consulte también:

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.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function and an argument if the key does not already exist, or returns the existing value if the key exists.

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 valueFactorypasar a.The type of an argument to pass into valueFactory.

Parámetros

key
TKey

Clave del elemento que se va a agregar.The key of the element to add.

valueFactory
Func<TKey,TArg,TValue>

Función que se usa para generar un valor para la clave.The function used to generate a value for the key.

factoryArgument
TArg

Valor de argumento que se pasará a valueFactory.An argument value to pass into valueFactory.

Devoluciones

TValue

Valor de la clave.The value for the key. 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.This will be either the existing value for the key if the key is already in the dictionary, or the new value if the key was not in the dictionary.

Excepciones

key es una referencia null (Nothing en Visual Basic).key is a null reference (Nothing in Visual Basic).

El diccionario contiene demasiados elementos.The dictionary contains too many elements.

Comentarios

En el caso de las modificaciones y las operaciones ConcurrentDictionary<TKey,TValue> de escritura en el diccionario, usa un bloqueo preciso para garantizar la seguridad para subprocesos.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (Las operaciones de lectura en el diccionario se realizan sin bloqueos). Sin embargo, valueFactory se llama al delegado fuera de los bloqueos para evitar los problemas que pueden surgir al ejecutar código desconocido en un bloqueo.(Read operations on the dictionary are performed in a lock-free manner.) However, the valueFactory delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Por lo GetOrAdd tanto, no es atómico con respecto a todas las demás ConcurrentDictionary<TKey,TValue> operaciones en la clase.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Puesto que un subproceso puede insertar un valor o clave, valueFactory mientras se genera un valor, no puede confiar en que valueFactory , simplemente porque se ejecuta, su valor generado se insertará en el Diccionario y se devolverá.Since a key/value can be inserted by another thread while valueFactory is generating a value, you cannot trust that just because valueFactory executed, its produced value will be inserted into the dictionary and returned. Si llama GetOrAdd a simultáneamente en diferentes subprocesos, valueFactory se puede llamar varias veces a, pero solo se agregará un par clave-valor al diccionario.If you call GetOrAdd simultaneously on different threads, valueFactory may be called multiple times, but only one key/value pair will be added to the dictionary.

El valor devuelto depende de la presencia de la clave en el Diccionario y de si un subproceso inserta una clave o un GetOrAdd valor después de que valueFactory se llame a, pero antes de que genere un valor:The return value depends on the presence of the key in the dictionary and whether a key/value is inserted by another thread after GetOrAdd is called but before valueFactory generates a value:

EscenarioScenario Valor devueltoReturn value
La clave ya está en el diccionario.The key is already in the dictionary. Se devuelve el valor existente.The existing value is returned.
La clave no está en el diccionario.The key is not in the dictionary. valueFactorygenera un valor.valueFactory generates a value. Al volver a comprobar la clave, no se encuentra ninguna clave.On rechecking for the key, no key is found. La clave/valor se inserta en el Diccionario y se devuelve el valor.The key/value is inserted into the dictionary, and the value is returned.
La clave no está en el diccionario.The key is not in the dictionary. valueFactorygenera un valor.valueFactory generates a value. Mientras valueFactory genera el valor, otro subproceso inserta un valor para la clave.While valueFactory is generating the value, a different thread inserts a value for the key. Después valueFactory de que se ejecute y al volver a comprobar la clave, se encuentra la clave insertada por el otro subproceso.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. Se devuelve el valor insertado por el otro subproceso.The value inserted by the other thread is returned.

Se aplica a