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>

Функция, используемая для создания значения ключа.

Возвращаемое значение

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

Добавляемое значение, если ключ еще не существует.

Возвращаемое значение

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в .

Возвращаемое значение

TValue

Значение ключа. Это будет либо существующее значение ключа, если ключ уже находится в словаре, либо новое значение, если ключ не был в словаре.

Исключения

key — это ссылка null (Ничего в Visual Basic).

Словарь содержит слишком много элементов.

Комментарии

Для изменений и операций записи в словарь ConcurrentDictionary<TKey,TValue> использует детальное блокировку для обеспечения безопасности потока. (Операции чтения в словаре выполняются без блокировки.) Однако делегат вызывается за пределами блокировок, valueFactory чтобы избежать проблем, которые могут возникнуть из-за выполнения неизвестного кода под блокировкой. GetOrAdd Поэтому не является атомарным в отношении всех других операций ConcurrentDictionary<TKey,TValue> класса.

Так как ключ или значение можно вставить другим потоком во время valueFactory создания значения, вы не можете доверять тому, что только потому valueFactory , что выполнено, его созданное значение будет вставлено в словарь и возвращено. При одновременном вызове GetOrAdd разных потоков valueFactory может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".

Возвращаемое значение зависит от наличия ключа в словаре и вставки ключа или значения другим потоком после GetOrAdd вызова, но перед valueFactory созданием значения:

Scenario Возвращаемое значение
Ключ уже находится в словаре. Возвращается существующее значение.
Ключ не находится в словаре. valueFactory создает значение. При повторной настройке ключа ключ не найден. Ключ или значение вставляется в словарь, и возвращается значение.
Ключ не находится в словаре. valueFactory создает значение. При valueFactory создании значения другой поток вставляет значение для ключа. После valueFactory выполнения и повторной проверки ключа будет найден ключ, вставленный другим потоком. Возвращается значение, вставленное другим потоком.

Применяется к