ConcurrentDictionary<TKey,TValue>.GetOrAdd Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
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
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
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
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. |