ConcurrentDictionary<TKey,TValue>.AddOrUpdate Método
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Adiciona um par chave/valor a ConcurrentDictionary<TKey,TValue> se a chave ainda não existir, ou atualiza um par chave/valor em ConcurrentDictionary<TKey,TValue> se a chave já existir.
Sobrecargas
| Name | Description |
|---|---|
| AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>) |
Usa as funções especificadas para adicionar um par chave/valor ao ConcurrentDictionary<TKey,TValue> caso a chave ainda não exista, ou para atualizar um par chave/valor no ConcurrentDictionary<TKey,TValue> caso a chave já exista. |
| AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>) |
Adiciona um par chave/valor a se ConcurrentDictionary<TKey,TValue> a chave ainda não existir, ou atualiza um par chave/valor em ConcurrentDictionary<TKey,TValue> usando a função especificada se a chave já existir. |
| AddOrUpdate<TArg>(TKey, Func<TKey,TArg,TValue>, Func<TKey,TValue,TArg,TValue>, TArg) |
Utiliza as funções e argumentos especificados para adicionar um par chave/valor ao ConcurrentDictionary<TKey,TValue> caso a chave ainda não exista, ou para atualizar um par chave/valor no ConcurrentDictionary<TKey,TValue> caso da chave já exista. |
Exemplos
O exemplo seguinte mostra como chamar o AddOrUpdate 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
AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)
Usa as funções especificadas para adicionar um par chave/valor ao ConcurrentDictionary<TKey,TValue> caso a chave ainda não exista, ou para atualizar um par chave/valor no ConcurrentDictionary<TKey,TValue> caso a chave já exista.
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
Parâmetros
- key
- TKey
A chave a acrescentar ou cujo valor deve ser atualizado.
- addValueFactory
- Func<TKey,TValue>
A função usada para gerar um valor para uma chave ausente.
- updateValueFactory
- Func<TKey,TValue,TValue>
A função utilizada para gerar um novo valor para uma chave existente com base no valor existente da chave.
Devoluções
O novo valor para a chave. Isto será ou o resultado de addValueFactory (se a chave estivesse ausente) ou o resultado de updateValueFactory (se a chave estivesse presente).
Exceções
key, addValueFactory, ou updateValueFactory é null.
O dicionário contém demasiados elementos.
Observações
Se chamar AddOrUpdate simultaneamente em diferentes threads, addValueFactory pode ser chamado várias vezes, mas o par chave/valor pode não ser adicionado ao dicionário para cada chamada.
Para modificações e operações de escrita no dicionário, ConcurrentDictionary<TKey,TValue> utiliza bloqueio de granulação fina para garantir a segurança das threads (as operações de leitura no dicionário são realizadas de forma sem bloqueios). Os addValueFactory delegados e updateValueFactory podem ser executados várias vezes para verificar se o valor foi adicionado ou atualizado conforme esperado. No entanto, são chamadas para fora das fechaduras para evitar os problemas que podem surgir ao executar código desconhecido sob uma fechadura. Portanto, AddOrUpdate não é atómico relativamente a todas as outras operações na ConcurrentDictionary<TKey,TValue> classe.
Ver também
Aplica-se a
AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)
Adiciona um par chave/valor a se ConcurrentDictionary<TKey,TValue> a chave ainda não existir, ou atualiza um par chave/valor em ConcurrentDictionary<TKey,TValue> usando a função especificada se a chave já existir.
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
Parâmetros
- key
- TKey
A chave a acrescentar ou cujo valor deve ser atualizado.
- addValue
- TValue
O valor a acrescentar por uma chave ausente.
- updateValueFactory
- Func<TKey,TValue,TValue>
A função utilizada para gerar um novo valor para uma chave existente com base no valor existente da chave.
Devoluções
O novo valor para a chave. Isto será ou ser addValue (se a chave estivesse ausente) ou o resultado de updateValueFactory (se a chave estivesse presente).
Exceções
key ou updateValueFactory é null.
O dicionário contém demasiados elementos.
Exemplos
O exemplo de código seguinte mostra como inicializar um ConcurrentDictionary<TKey,TValue> e como usar o método AddOrUpdate para adicionar um item adicional à coleção e atualizar os itens existentes.
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
Para modificações e operações de escrita no dicionário, ConcurrentDictionary<TKey,TValue> utiliza bloqueio de granulação fina para garantir a segurança das threads. (As operações de leitura no dicionário são realizadas de forma sem bloqueios.) Os addValueFactory delegados e updateValueFactory podem ser executados várias vezes para verificar se o valor foi adicionado ou atualizado conforme esperado. No entanto, são chamadas para fora das fechaduras para evitar os problemas que podem surgir ao executar código desconhecido sob uma fechadura. Portanto, AddOrUpdate não é atómico relativamente a todas as outras operações na ConcurrentDictionary<TKey,TValue> classe.
Ver também
Aplica-se a
AddOrUpdate<TArg>(TKey, Func<TKey,TArg,TValue>, Func<TKey,TValue,TArg,TValue>, TArg)
Utiliza as funções e argumentos especificados para adicionar um par chave/valor ao ConcurrentDictionary<TKey,TValue> caso a chave ainda não exista, ou para atualizar um par chave/valor no ConcurrentDictionary<TKey,TValue> caso da chave já exista.
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
Parâmetros de Tipo Genérico
- TArg
O tipo de argumento a passar para addValueFactory e updateValueFactory.
Parâmetros
- key
- TKey
A chave a acrescentar ou cujo valor deve ser atualizado.
- addValueFactory
- Func<TKey,TArg,TValue>
A função usada para gerar um valor para uma chave ausente.
- updateValueFactory
- Func<TKey,TValue,TArg,TValue>
A função utilizada para gerar um novo valor para uma chave existente com base no valor existente da chave.
- factoryArgument
- TArg
Um argumento para passar em addValueFactory e updateValueFactory.
Devoluções
O novo valor para a chave. Isto será ou o resultado de addValueFactory (se a chave estivesse ausente) ou o resultado de updateValueFactory (se a chave estivesse presente).
Exceções
key, addValueFactory ou updateValueFactory é uma referência nula (Nada em Visual Basic).
O dicionário contém demasiados elementos.
Observações
Se chamar AddOrUpdate simultaneamente em diferentes threads, addValueFactory pode ser chamado várias vezes, mas o par chave/valor pode não ser adicionado ao dicionário para cada chamada.
Para modificações e operações de escrita no dicionário, ConcurrentDictionary<TKey,TValue> utiliza bloqueio de granulação fina para garantir a segurança das threads. (As operações de leitura no dicionário são realizadas de forma sem bloqueios.) Os addValueFactory delegados e updateValueFactory podem ser executados várias vezes para verificar se o valor foi adicionado ou atualizado conforme esperado. No entanto, são chamadas para fora das fechaduras para evitar os problemas que podem surgir ao executar código desconhecido sob uma fechadura. Portanto, AddOrUpdate não é atómico relativamente a todas as outras operações na ConcurrentDictionary<TKey,TValue> classe.