ConcurrentDictionary<TKey,TValue>.GetOrAdd Método

Definição

Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Retorna o novo valor ou o valor existente se a chave já existir.Returns the new value, or the existing value if the key already exists.

Sobrecargas

GetOrAdd(TKey, Func<TKey,TValue>)

Adiciona um par chave/valor para o ConcurrentDictionary<TKey,TValue> usando a função especificada, se a chave ainda não existir.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Retorna o novo valor ou o valor existente se a chave existir.Returns the new value, or the existing value if the key exists.

GetOrAdd(TKey, TValue)

Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Retorna o novo valor ou o valor existente se a chave existir.Returns the new value, or the existing value if the key exists.

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

Adiciona um par chave/valor ao ConcurrentDictionary<TKey,TValue> usando o argumento e a função especificada se a chave ainda não existir ou retorna o valor existente se a chave já existir.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.

Exemplos

O exemplo a seguir mostra como chamar o método GetOrAdd: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>)

Adiciona um par chave/valor para o ConcurrentDictionary<TKey,TValue> usando a função especificada, se a chave ainda não existir.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Retorna o novo valor ou o valor existente se a chave existir.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

A chave do elemento a ser adicionada.The key of the element to add.

valueFactory
Func<TKey,TValue>

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

Retornos

TValue

O valor da chave.The value for the key. Esse será o valor existente da chave se ela já estiver no dicionário ou o novo valor se ela não estiver no dicionário.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.

Exceções

key ou valueFactory é null.key or valueFactory is null.

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

Comentários

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 valueFactory é 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 valueFactory delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Portanto, GetOrAdd não é atômica com relação a todas as outras operações na classe ConcurrentDictionary<TKey,TValue>.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Como uma chave/valor pode ser inserida por outro thread enquanto valueFactory está gerando um valor, você não pode confiar que só porque valueFactory executado, seu valor produzido será inserido no dicionário e retornado.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. Se você chamar GetOrAdd simultaneamente em threads diferentes, valueFactory poderá ser chamado várias vezes, mas apenas um par de chave/valor será adicionado ao dicionário.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.

O valor de retorno depende da presença da chave no dicionário e se uma chave/valor é inserido por outro thread depois que GetOrAdd é chamado, mas antes de valueFactory gerar um 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:

CenárioScenario Valor retornadoReturn value
A chave já está no dicionário.The key is already in the dictionary. O valor existente é retornado.The existing value is returned.
A chave não está no dicionário.The key is not in the dictionary. valueFactory gera um valor.valueFactory generates a value. Ao verificar novamente a chave, nenhuma chave é encontrada.On rechecking for the key, no key is found. A chave/valor é inserida no dicionário e o valor é retornado.The key/value is inserted into the dictionary, and the value is returned.
A chave não está no dicionário.The key is not in the dictionary. valueFactory gera um valor.valueFactory generates a value. Embora valueFactory esteja gerando o valor, um thread diferente insere um valor para a chave.While valueFactory is generating the value, a different thread inserts a value for the key. Depois que valueFactory é executado e depois de verificar a chave, a chave inserida pelo outro thread é encontrada.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. O valor inserido pelo outro thread é retornado.The value inserted by the other thread is returned.

Veja também

GetOrAdd(TKey, TValue)

Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Retorna o novo valor ou o valor existente se a chave existir.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

A chave do elemento a ser adicionada.The key of the element to add.

value
TValue

O valor a ser adicionado se a chave ainda não existir.The value to be added, if the key does not already exist.

Retornos

TValue

O valor da chave.The value for the key. Esse será o valor existente da chave se ela já estiver no dicionário ou o novo valor se ela não estiver no dicionário.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.

Exceções

key é null.key is null.

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

Veja também

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

Adiciona um par chave/valor ao ConcurrentDictionary<TKey,TValue> usando o argumento e a função especificada se a chave ainda não existir ou retorna o valor existente se a chave já existir.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

O tipo de um argumento para passar para valueFactory.The type of an argument to pass into valueFactory.

Parâmetros

key
TKey

A chave do elemento a ser adicionada.The key of the element to add.

valueFactory
Func<TKey,TArg,TValue>

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

factoryArgument
TArg

Um valor de argumento para passar para valueFactory.An argument value to pass into valueFactory.

Retornos

TValue

O valor da chave.The value for the key. Esse será o valor existente da chave se ela já estiver no dicionário ou o novo valor se ela não estiver no dicionário.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.

Exceções

key é uma referência null (Nothing no Visual Basic).key is a null reference (Nothing in Visual Basic).

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

Comentários

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 valueFactory é 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 valueFactory delegate is called outside the locks to avoid the problems that can arise from executing unknown code under a lock. Portanto, GetOrAdd não é atômica com relação a todas as outras operações na classe ConcurrentDictionary<TKey,TValue>.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Como uma chave/valor pode ser inserida por outro thread enquanto valueFactory está gerando um valor, você não pode confiar que só porque valueFactory executado, seu valor produzido será inserido no dicionário e retornado.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. Se você chamar GetOrAdd simultaneamente em threads diferentes, valueFactory poderá ser chamado várias vezes, mas apenas um par de chave/valor será adicionado ao dicionário.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.

O valor de retorno depende da presença da chave no dicionário e se uma chave/valor é inserido por outro thread depois que GetOrAdd é chamado, mas antes de valueFactory gerar um 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:

CenárioScenario Valor retornadoReturn value
A chave já está no dicionário.The key is already in the dictionary. O valor existente é retornado.The existing value is returned.
A chave não está no dicionário.The key is not in the dictionary. valueFactory gera um valor.valueFactory generates a value. Ao verificar novamente a chave, nenhuma chave é encontrada.On rechecking for the key, no key is found. A chave/valor é inserida no dicionário e o valor é retornado.The key/value is inserted into the dictionary, and the value is returned.
A chave não está no dicionário.The key is not in the dictionary. valueFactory gera um valor.valueFactory generates a value. Embora valueFactory esteja gerando o valor, um thread diferente insere um valor para a chave.While valueFactory is generating the value, a different thread inserts a value for the key. Depois que valueFactory é executado e depois de verificar a chave, a chave inserida pelo outro thread é encontrada.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. O valor inserido pelo outro thread é retornado.The value inserted by the other thread is returned.

Aplica-se a