ConcurrentDictionary<TKey,TValue>.GetOrAdd Método
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe. Retorna o novo valor ou o valor existente se a chave já existir.
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. Retorna o novo valor ou o valor existente se a chave existir. |
GetOrAdd(TKey, TValue) |
Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe. Retorna o novo valor ou o valor existente se a chave existir. |
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. |
Exemplos
O exemplo a seguir mostra como chamar o 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>)
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
Adiciona um par chave/valor para o ConcurrentDictionary<TKey,TValue> usando a função especificada, se a chave ainda não existir. Retorna o novo valor ou o valor existente se a chave existir.
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.
- valueFactory
- Func<TKey,TValue>
A função usada para gerar um valor para a chave.
Retornos
O valor da chave. 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.
Exceções
key
ou valueFactory
é null
.
O dicionário contém muitos elementos.
Comentários
Para modificações e operações de gravação no dicionário, ConcurrentDictionary<TKey,TValue> o usa o bloqueio refinado para garantir a segurança do thread. (As operações de leitura no dicionário são executadas de maneira livre de bloqueios.) No entanto, o valueFactory
delegado é chamado fora dos bloqueios para evitar os problemas que podem surgir da execução de código desconhecido em um bloqueio. Portanto, GetOrAdd não é atômico em relação a todas as outras operações na ConcurrentDictionary<TKey,TValue> classe .
Como uma chave/valor pode ser inserido por outro thread enquanto valueFactory
está gerando um valor, você não pode confiar nisso apenas porque valueFactory
executado, seu valor produzido será inserido no dicionário e retornado. Se você chamar GetOrAdd simultaneamente em threads diferentes, valueFactory
poderá ser chamado várias vezes, mas apenas um par chave/valor será adicionado ao dicionário.
O valor retornado depende da presença da chave no dicionário e se uma chave/valor é inserido por outro thread depois GetOrAdd de ser chamado, mas antes valueFactory
gera um valor:
Cenário | Valor retornado |
---|---|
A chave já está no dicionário. | O valor existente é retornado. |
A chave não está no dicionário. valueFactory gera um valor . Ao verificar novamente a chave, nenhuma chave é encontrada. |
A chave/valor é inserido no dicionário e o valor é retornado. |
A chave não está no dicionário. valueFactory gera um valor . Enquanto valueFactory está gerando o valor, um thread diferente insere um valor para a chave. Depois valueFactory de executar e ao verificar novamente a chave, a chave inserida pelo outro thread será encontrada. |
O valor inserido pelo outro thread é retornado. |
Confira também
Aplica-se a
GetOrAdd(TKey, TValue)
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
Adiciona um par chave-valor ao ConcurrentDictionary<TKey,TValue> se a chave ainda não existe. Retorna o novo valor ou o valor existente se a chave existir.
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.
- value
- TValue
O valor a ser adicionado se a chave ainda não existir.
Retornos
O valor da chave. 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.
Exceções
key
é null
.
O dicionário contém muitos elementos.
Confira também
Aplica-se a
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
- Origem:
- ConcurrentDictionary.cs
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.
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 a ser passado para valueFactory
.
Parâmetros
- key
- TKey
A chave do elemento a ser adicionada.
- valueFactory
- Func<TKey,TArg,TValue>
A função usada para gerar um valor para a chave.
- factoryArgument
- TArg
Um valor de argumento para passar para valueFactory
.
Retornos
O valor da chave. 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.
Exceções
key
é uma referência null
(Nothing no Visual Basic).
O dicionário contém muitos elementos.
Comentários
Para modificações e operações de gravação no dicionário, ConcurrentDictionary<TKey,TValue> o usa o bloqueio refinado para garantir a segurança do thread. (As operações de leitura no dicionário são executadas de maneira livre de bloqueios.) No entanto, o valueFactory
delegado é chamado fora dos bloqueios para evitar os problemas que podem surgir da execução de código desconhecido em um bloqueio. Portanto, GetOrAdd não é atômico em relação a todas as outras operações na ConcurrentDictionary<TKey,TValue> classe .
Como uma chave/valor pode ser inserido por outro thread enquanto valueFactory
está gerando um valor, você não pode confiar nisso apenas porque valueFactory
executado, seu valor produzido será inserido no dicionário e retornado. Se você chamar GetOrAdd simultaneamente em threads diferentes, valueFactory
poderá ser chamado várias vezes, mas apenas um par chave/valor será adicionado ao dicionário.
O valor retornado depende da presença da chave no dicionário e se uma chave/valor é inserido por outro thread depois GetOrAdd de ser chamado, mas antes valueFactory
gera um valor:
Cenário | Valor retornado |
---|---|
A chave já está no dicionário. | O valor existente é retornado. |
A chave não está no dicionário. valueFactory gera um valor . Ao verificar novamente a chave, nenhuma chave é encontrada. |
A chave/valor é inserido no dicionário e o valor é retornado. |
A chave não está no dicionário. valueFactory gera um valor . Enquanto valueFactory está gerando o valor, um thread diferente insere um valor para a chave. Depois valueFactory de executar e ao verificar novamente a chave, a chave inserida pelo outro thread será encontrada. |
O valor inserido pelo outro thread é retornado. |