ConcurrentDictionary<TKey,TValue>.AddOrUpdate Método

Definição

Adiciona um par chave/valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou atualiza um par chave/valor no ConcurrentDictionary<TKey,TValue> se a chave já existir.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or updates a key/value pair in the ConcurrentDictionary<TKey,TValue> if the key already exists.

Sobrecargas

AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

Usará as funções especificadas para adicionar um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou para atualizar um par chave-valor no ConcurrentDictionary<TKey,TValue> se a chave já existir.Uses the specified functions to add a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or to update a key/value pair in the ConcurrentDictionary<TKey,TValue> if the key already exists.

AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)

Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou atualiza um par chave-valor no ConcurrentDictionary<TKey,TValue> usando a função especificada se a chave já existir.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or updates a key/value pair in the ConcurrentDictionary<TKey,TValue> by using the specified function if the key already exists.

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

Usará o argumento e as funções especificadas para adicionar um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou para atualizar um par chave-valor no ConcurrentDictionary<TKey,TValue> se a chave já existir.Uses the specified functions and argument to add a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or to update a key/value pair in the ConcurrentDictionary<TKey,TValue> if the key already exists.

Exemplos

O exemplo a seguir mostra como chamar o método AddOrUpdate:The following example shows how to call the AddOrUpdate 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

AddOrUpdate(TKey, Func<TKey,TValue>, Func<TKey,TValue,TValue>)

Usará as funções especificadas para adicionar um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou para atualizar um par chave-valor no ConcurrentDictionary<TKey,TValue> se a chave já existir.Uses the specified functions to add a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or to update a key/value pair in the ConcurrentDictionary<TKey,TValue> if the key already exists.

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 ser adicionada ou cujo valor deve ser atualizadoThe key to be added or whose value should be updated

addValueFactory
Func<TKey,TValue>

A função usada para gerar um valor para uma chave ausenteThe function used to generate a value for an absent key

updateValueFactory
Func<TKey,TValue,TValue>

A função usada para gerar um novo valor para uma chave existente com base no valor existente da chaveThe function used to generate a new value for an existing key based on the key's existing value

Retornos

TValue

O novo valor da chave.The new value for the key. Esse será o resultado de addValueFactory (se a chave estava ausente) ou o resultado de updateValueFactory (se a chave estava presente).This will be either be the result of addValueFactory (if the key was absent) or the result of updateValueFactory (if the key was present).

Exceções

key, addValueFactory ou updateValueFactory é null.key, addValueFactory, or updateValueFactory is null.

O dicionário contém muitos elementos.The dictionary contains too many elements.

Comentários

Se você chamar AddOrUpdate simultaneamente em threads diferentes, addValueFactory poderá ser chamado várias vezes, mas seu par de chave/valor pode não ser adicionado ao dicionário para cada chamada.If you call AddOrUpdate simultaneously on different threads, addValueFactory may be called multiple times, but its key/value pair might not be added to the dictionary for every call.

Para modificações e operações de gravação no dicionário, ConcurrentDictionary<TKey,TValue> usa o bloqueio refinado para garantir a segurança do thread.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (As operações de leitura no dicionário são executadas de maneira sem bloqueio.) No entanto, os delegados de addValueFactory e updateValueFactory são chamados fora dos bloqueios para evitar os problemas que podem surgir na execução de um código desconhecido em um bloqueio.(Read operations on the dictionary are performed in a lock-free manner.) However, the addValueFactory and updateValueFactory delegates are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Portanto, AddOrUpdate não é atômica com relação a todas as outras operações na classe ConcurrentDictionary<TKey,TValue>.Therefore, AddOrUpdate is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Veja também

AddOrUpdate(TKey, TValue, Func<TKey,TValue,TValue>)

Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou atualiza um par chave-valor no ConcurrentDictionary<TKey,TValue> usando a função especificada se a chave já existir.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or updates a key/value pair in the ConcurrentDictionary<TKey,TValue> by using the specified function if the key already exists.

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 ser adicionada ou cujo valor deve ser atualizadoThe key to be added or whose value should be updated

addValue
TValue

O valor a ser adicionado para uma chave ausenteThe value to be added for an absent key

updateValueFactory
Func<TKey,TValue,TValue>

A função usada para gerar um novo valor para uma chave existente com base no valor existente da chaveThe function used to generate a new value for an existing key based on the key's existing value

Retornos

TValue

O novo valor da chave.The new value for the key. Será addValue (se a chave estava ausente) ou o resultado de updateValueFactory (se a chave estava presente).This will be either be addValue (if the key was absent) or the result of updateValueFactory (if the key was present).

Exceções

key ou updateValueFactory é null.key or updateValueFactory is null.

O dicionário contém muitos elementos.The dictionary contains too many elements.

Exemplos

O exemplo de código a seguir 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.The following code example shows how to initialize an ConcurrentDictionary<TKey,TValue> and how to use the AddOrUpdate method to add an additional item to the collection, and update the existing items.

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)));
    }
}
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 gravação no dicionário, ConcurrentDictionary<TKey,TValue> usa o bloqueio refinado para garantir a segurança do thread.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (As operações de leitura no dicionário são executadas de maneira sem bloqueio.) No entanto, o delegado updateValueFactory é chamado fora dos bloqueios para evitar os problemas que podem surgir na execução de um código desconhecido em um bloqueio.(Read operations on the dictionary are performed in a lock-free manner.) However, the updateValueFactory delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Portanto, AddOrUpdate não é atômica com relação a todas as outras operações na classe ConcurrentDictionary<TKey,TValue>.Therefore, AddOrUpdate is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Veja também

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

Usará o argumento e as funções especificadas para adicionar um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existir ou para atualizar um par chave-valor no ConcurrentDictionary<TKey,TValue> se a chave já existir.Uses the specified functions and argument to add a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist, or to update a key/value pair in the ConcurrentDictionary<TKey,TValue> if the key already exists.

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

TArg

O tipo de um argumento a ser passado para addValueFactory e updateValueFactory.The type of an argument to pass into addValueFactory and updateValueFactory.

Parâmetros

key
TKey

A chave a ser adicionada ou cujo valor deve ser atualizado.The key to be added or whose value should be updated.

addValueFactory
Func<TKey,TArg,TValue>

A função usada para gerar um valor para uma chave ausente.The function used to generate a value for an absent key.

updateValueFactory
Func<TKey,TValue,TArg,TValue>

A função usada para gerar um novo valor para uma chave existente com base no valor existente da chave.The function used to generate a new value for an existing key based on the key's existing value.

factoryArgument
TArg

Um argumento a passar para addValueFactory e updateValueFactory.An argument to pass into addValueFactory and updateValueFactory.

Retornos

TValue

O novo valor da chave.The new value for the key. Esse será o resultado de addValueFactory (se a chave estava ausente) ou o resultado de updateValueFactory (se a chave estava presente).This will be either be the result of addValueFactory (if the key was absent) or the result of updateValueFactory (if the key was present).

Exceções

key, addValueFactory ou updateValueFactory é uma referência nula (Nothing no Visual Basic).key, addValueFactory, or updateValueFactory is a null reference (Nothing in Visual Basic).

O dicionário contém muitos elementos.The dictionary contains too many elements.

Comentários

Se você chamar AddOrUpdate simultaneamente em threads diferentes, addValueFactory poderá ser chamado várias vezes, mas seu par de chave/valor pode não ser adicionado ao dicionário para cada chamada.If you call AddOrUpdate simultaneously on different threads, addValueFactory may be called multiple times, but its key/value pair might not be added to the dictionary for every call.

Para modificações e operações de gravação no dicionário, ConcurrentDictionary<TKey,TValue> usa o bloqueio refinado para garantir a segurança do thread.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (As operações de leitura no dicionário são executadas de maneira sem bloqueio.) No entanto, os delegados de addValueFactory e updateValueFactory são chamados fora dos bloqueios para evitar os problemas que podem surgir na execução de um código desconhecido em um bloqueio.(Read operations on the dictionary are performed in a lock-free manner.) However, the addValueFactory and updateValueFactory delegates are called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Portanto, AddOrUpdate não é atômica com relação a todas as outras operações na classe ConcurrentDictionary<TKey,TValue>.Therefore, AddOrUpdate is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Aplica-se a