ConcurrentDictionary<TKey,TValue>.GetOrAdd Метод
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует. Возвращает новое значение или существующее значение, если ключ существует.
Перегрузки
GetOrAdd(TKey, Func<TKey,TValue>) |
Добавляет пару "ключ-значение" в ConcurrentDictionary<TKey,TValue>, используя указанную функцию, если ключ еще не существует. Возвращает новое значение или существующее значение, если ключ существует. |
GetOrAdd(TKey, TValue) |
Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует. Возвращает новое значение или существующее значение, если ключ существует. |
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg) |
Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, используя указанную функцию и аргумент, если этот ключ еще не существует, или возвращает существующее значение при наличии ключа. |
Примеры
В следующем примере показано, как вызвать GetOrAdd метод :
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>)
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
Добавляет пару "ключ-значение" в ConcurrentDictionary<TKey,TValue>, используя указанную функцию, если ключ еще не существует. Возвращает новое значение или существующее значение, если ключ существует.
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
Параметры
- key
- TKey
Ключ добавляемого элемента.
- valueFactory
- Func<TKey,TValue>
Функция, используемая для создания значения для ключа.
Возвращаемое значение
Значение для ключа. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новое значение, если ключ не существовал в словаре.
Исключения
Параметр key
или valueFactory
имеет значение null
.
Словарь содержит слишком много элементов.
Комментарии
Для операций изменения и записи в словарь использует детализированную блокировку для ConcurrentDictionary<TKey,TValue> обеспечения потокобезопасности. (Операции чтения в словаре выполняются без блокировки.) Однако делегат вызывается вне блокировок, valueFactory
чтобы избежать проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой. Таким образом, GetOrAdd не является атомарным по отношению ко всем остальным операциям в ConcurrentDictionary<TKey,TValue> классе .
Так как ключ/значение может быть вставлен другим потоком во время valueFactory
создания значения, вы не можете доверять ему только потому, что valueFactory
выполнено, созданное значение будет вставлено в словарь и возвращено. При одновременном вызове GetOrAdd в разных потоках valueFactory
может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".
Возвращаемое значение зависит от наличия ключа в словаре и от того, вставляется ли ключ или значение другим потоком после GetOrAdd вызова , но до valueFactory
создания значения:
Сценарий | Возвращаемое значение |
---|---|
Ключ уже находится в словаре. | Возвращается существующее значение. |
Ключ отсутствует в словаре. valueFactory создает значение . При повторной проверки ключа ключ не найден. |
Ключ/значение вставляется в словарь и возвращается значение. |
Ключ отсутствует в словаре. valueFactory создает значение . При valueFactory создании значения другой поток вставляет значение для ключа. После valueFactory выполнения и повторной проверки ключа обнаруживается ключ, вставленный другим потоком. |
Возвращается значение, вставленное другим потоком. |
См. также раздел
- Потокобезопасные коллекции
- Практическое руководство. Добавление элементов в коллекцию ConcurrentDictionary и их удаление из этой коллекции
Применяется к
GetOrAdd(TKey, TValue)
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует. Возвращает новое значение или существующее значение, если ключ существует.
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
Параметры
- key
- TKey
Ключ добавляемого элемента.
- value
- TValue
Значение, которое необходимо добавить, если ключ еще не существует.
Возвращаемое значение
Значение для ключа. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новое значение, если ключ не существовал в словаре.
Исключения
key
имеет значение null
.
Словарь содержит слишком много элементов.
См. также раздел
- Потокобезопасные коллекции
- Практическое руководство. Добавление элементов в коллекцию ConcurrentDictionary и их удаление из этой коллекции
Применяется к
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, используя указанную функцию и аргумент, если этот ключ еще не существует, или возвращает существующее значение при наличии ключа.
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
Параметры типа
- TArg
Тип аргумента, передаваемого в valueFactory
.
Параметры
- key
- TKey
Ключ добавляемого элемента.
- valueFactory
- Func<TKey,TArg,TValue>
Функция, используемая для создания значения для ключа.
- factoryArgument
- TArg
Значение аргумента, передаваемое в valueFactory
.
Возвращаемое значение
Значение для ключа. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новое значение, если ключ не существовал в словаре.
Исключения
key
является ссылкой null
(Nothing в Visual Basic).
Словарь содержит слишком много элементов.
Комментарии
Для операций изменения и записи в словарь использует детализированную блокировку для ConcurrentDictionary<TKey,TValue> обеспечения потокобезопасности. (Операции чтения в словаре выполняются без блокировки.) Однако делегат вызывается вне блокировок, valueFactory
чтобы избежать проблем, которые могут возникнуть при выполнении неизвестного кода под блокировкой. Таким образом, GetOrAdd не является атомарным по отношению ко всем остальным операциям в ConcurrentDictionary<TKey,TValue> классе .
Так как ключ/значение может быть вставлен другим потоком во время valueFactory
создания значения, вы не можете доверять ему только потому, что valueFactory
выполнено, созданное значение будет вставлено в словарь и возвращено. При одновременном вызове GetOrAdd в разных потоках valueFactory
может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".
Возвращаемое значение зависит от наличия ключа в словаре и от того, вставляется ли ключ или значение другим потоком после GetOrAdd вызова , но до valueFactory
создания значения:
Сценарий | Возвращаемое значение |
---|---|
Ключ уже находится в словаре. | Возвращается существующее значение. |
Ключ отсутствует в словаре. valueFactory создает значение . При повторной проверки ключа ключ не найден. |
Ключ/значение вставляется в словарь и возвращается значение. |
Ключ отсутствует в словаре. valueFactory создает значение . При valueFactory создании значения другой поток вставляет значение для ключа. После valueFactory выполнения и повторной проверки ключа обнаруживается ключ, вставленный другим потоком. |
Возвращается значение, вставленное другим потоком. |