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.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 созданием значения:
| Scenario | Возвращаемое значение |
|---|---|
| Ключ уже находится в словаре. | Возвращается существующее значение. |
Ключ не находится в словаре.
valueFactory создает значение. При повторной настройке ключа ключ не найден. |
Ключ или значение вставляется в словарь, и возвращается значение. |
Ключ не находится в словаре.
valueFactory создает значение. При valueFactory создании значения другой поток вставляет значение для ключа. После valueFactory выполнения и повторной проверки ключа будет найден ключ, вставленный другим потоком. |
Возвращается значение, вставленное другим потоком. |
См. также раздел
Применяется к
GetOrAdd(TKey, TValue)
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- 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.
Словарь содержит слишком много элементов.
См. также раздел
Применяется к
GetOrAdd<TArg>(TKey, Func<TKey,TArg,TValue>, TArg)
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- ConcurrentDictionary.cs
- Исходный код:
- 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) where TArg : allows ref struct;
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 (Ничего в Visual Basic).
Словарь содержит слишком много элементов.
Комментарии
Для изменений и операций записи в словарь ConcurrentDictionary<TKey,TValue> использует детальное блокировку для обеспечения безопасности потока. (Операции чтения в словаре выполняются без блокировки.) Однако делегат вызывается за пределами блокировок, valueFactory чтобы избежать проблем, которые могут возникнуть из-за выполнения неизвестного кода под блокировкой.
GetOrAdd Поэтому не является атомарным в отношении всех других операций ConcurrentDictionary<TKey,TValue> класса.
Так как ключ или значение можно вставить другим потоком во время valueFactory создания значения, вы не можете доверять тому, что только потому valueFactory , что выполнено, его созданное значение будет вставлено в словарь и возвращено. При одновременном вызове GetOrAdd разных потоков valueFactory может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".
Возвращаемое значение зависит от наличия ключа в словаре и вставки ключа или значения другим потоком после GetOrAdd вызова, но перед valueFactory созданием значения:
| Scenario | Возвращаемое значение |
|---|---|
| Ключ уже находится в словаре. | Возвращается существующее значение. |
Ключ не находится в словаре.
valueFactory создает значение. При повторной настройке ключа ключ не найден. |
Ключ или значение вставляется в словарь, и возвращается значение. |
Ключ не находится в словаре.
valueFactory создает значение. При valueFactory создании значения другой поток вставляет значение для ключа. После valueFactory выполнения и повторной проверки ключа будет найден ключ, вставленный другим потоком. |
Возвращается значение, вставленное другим потоком. |