ConcurrentDictionary<TKey,TValue>.GetOrAdd ConcurrentDictionary<TKey,TValue>.GetOrAdd ConcurrentDictionary<TKey,TValue>.GetOrAdd ConcurrentDictionary<TKey,TValue>.GetOrAdd Method

Определение

Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Возвращает новое значение или существующее значение, если ключ существует.Returns the new value, or the existing value if the key already exists.

Перегрузки

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

Добавляет пару "ключ-значение" в ConcurrentDictionary<TKey,TValue>, используя указанную функцию, если ключ еще не существует.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Возвращает новое значение или существующее значение, если ключ существует.Returns the new value, or the existing value if the key exists.

GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue)

Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Возвращает новое значение или существующее значение, если ключ существует.Returns the new value, or the existing value if the key exists.

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

Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, используя указанную функцию и аргумент, если этот ключ еще не существует, или возвращает существующее значение при наличии ключа.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.

Примеры

В следующем примере показано, как вызвать 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>) GetOrAdd(TKey, Func<TKey,TValue>) GetOrAdd(TKey, Func<TKey,TValue>) GetOrAdd(TKey, Func<TKey,TValue>)

Добавляет пару "ключ-значение" в ConcurrentDictionary<TKey,TValue>, используя указанную функцию, если ключ еще не существует.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> by using the specified function if the key does not already exist. Возвращает новое значение или существующее значение, если ключ существует.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

Параметры

key
TKey TKey TKey TKey

Ключ добавляемого элемента.The key of the element to add.

valueFactory
Func<TKey,TValue>

Функция, используемая для создания значения для ключа.The function used to generate a value for the key.

Возвраты

TValue TValue TValue TValue

Значение для ключа.The value for the key. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новым значением, если ключ не существовал в словаре.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.

Исключения

Значение параметра key или valueFactorynull.key or valueFactory is null.

Словарь уже содержит максимальное количество элементов (MaxValue).The dictionary already contains the maximum number of elements (MaxValue).

Комментарии

Для операций изменения и записи в словарь ConcurrentDictionary<TKey,TValue> использует детальную блокировку для обеспечения безопасности потоков.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (Операции чтения в словаре выполняются без блокировки.) valueFactory Однако делегат вызывается за пределами блокировок, чтобы избежать проблем, возникающих при выполнении неизвестного кода при блокировке.(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. Таким образом GetOrAdd , не является атомарным с точки зрения всех других операций ConcurrentDictionary<TKey,TValue> с классом.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Поскольку ключ или значение могут быть вставлены другим потоком при valueFactory формировании значения, нельзя доверять этому, только потому valueFactory что выполняется, его созданное значение будет вставлено в словарь и возвращено.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. При одновременном GetOrAdd вызове в разных valueFactory потоках метод может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".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.

Возвращаемое значение зависит от наличия ключа в словаре, а также от того, вставляется ли ключ или значение другим потоком после GetOrAdd вызова, но перед valueFactory созданием значения: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:

СценарийScenario Возвращаемое значениеReturn value
Ключ уже находится в словаре.The key is already in the dictionary. Возвращается существующее значение.The existing value is returned.
Ключ отсутствует в словаре.The key is not in the dictionary. valueFactoryсоздает значение.valueFactory generates a value. При перепроверке ключа ключ не найден.On rechecking for the key, no key is found. Ключ/значение вставляется в словарь и возвращается значение.The key/value is inserted into the dictionary, and the value is returned.
Ключ отсутствует в словаре.The key is not in the dictionary. valueFactoryсоздает значение.valueFactory generates a value. При valueFactory формировании значения другой поток вставляет значение для ключа.While valueFactory is generating the value, a different thread inserts a value for the key. После valueFactory выполнения и при повторе проверки ключа будет найден ключ, вставленный другим потоком.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. Возвращается значение, вставленное другим потоком.The value inserted by the other thread is returned.
Дополнительно

GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue) GetOrAdd(TKey, TValue)

Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, если ключ еще не существует.Adds a key/value pair to the ConcurrentDictionary<TKey,TValue> if the key does not already exist. Возвращает новое значение или существующее значение, если ключ существует.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

Параметры

key
TKey TKey TKey TKey

Ключ добавляемого элемента.The key of the element to add.

value
TValue TValue TValue TValue

Значение, которое необходимо добавить, если ключ еще не существует.The value to be added, if the key does not already exist.

Возвраты

TValue TValue TValue TValue

Значение для ключа.The value for the key. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новым значением, если ключ не существовал в словаре.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.

Исключения

Словарь уже содержит максимальное количество элементов (MaxValue).The dictionary already contains the maximum number of elements (MaxValue).

Дополнительно

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

Добавляет пару "ключ-значение" в коллекцию ConcurrentDictionary<TKey,TValue>, используя указанную функцию и аргумент, если этот ключ еще не существует, или возвращает существующее значение при наличии ключа.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

Параметры типа

TArg

Тип аргумента для передачи valueFactory.The type of an argument to pass into valueFactory.

Параметры

key
TKey TKey TKey TKey

Ключ добавляемого элемента.The key of the element to add.

valueFactory
Func<TKey,TArg,TValue>

Функция, используемая для создания значения для ключа.The function used to generate a value for the key.

factoryArgument

Значение аргумента, передаваемое в valueFactory.An argument value to pass into valueFactory.

Возвраты

TValue TValue TValue TValue

Значение для ключа.The value for the key. Этим значением будет существующее значение ключа, если ключ уже имеется в словаре, или новым значением, если ключ не существовал в словаре.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.

Исключения

key является ссылкой null (Nothing в Visual Basic).key is a null reference (Nothing in Visual Basic).

Словарь содержит слишком много элементов.The dictionary contains too many elements.

Комментарии

Для операций изменения и записи в словарь ConcurrentDictionary<TKey,TValue> использует детальную блокировку для обеспечения безопасности потоков.For modifications and write operations to the dictionary, ConcurrentDictionary<TKey,TValue> uses fine-grained locking to ensure thread safety. (Операции чтения в словаре выполняются без блокировки.) valueFactory Однако делегат вызывается за пределами блокировок, чтобы избежать проблем, возникающих при выполнении неизвестного кода при блокировке.(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. Таким образом GetOrAdd , не является атомарным с точки зрения всех других операций ConcurrentDictionary<TKey,TValue> с классом.Therefore, GetOrAdd is not atomic with regards to all other operations on the ConcurrentDictionary<TKey,TValue> class.

Поскольку ключ или значение могут быть вставлены другим потоком при valueFactory формировании значения, нельзя доверять этому, только потому valueFactory что выполняется, его созданное значение будет вставлено в словарь и возвращено.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. При одновременном GetOrAdd вызове в разных valueFactory потоках метод может вызываться несколько раз, но в словарь будет добавлена только одна пара "ключ-значение".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.

Возвращаемое значение зависит от наличия ключа в словаре, а также от того, вставляется ли ключ или значение другим потоком после GetOrAdd вызова, но перед valueFactory созданием значения: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:

СценарийScenario Возвращаемое значениеReturn value
Ключ уже находится в словаре.The key is already in the dictionary. Возвращается существующее значение.The existing value is returned.
Ключ отсутствует в словаре.The key is not in the dictionary. valueFactoryсоздает значение.valueFactory generates a value. При перепроверке ключа ключ не найден.On rechecking for the key, no key is found. Ключ/значение вставляется в словарь и возвращается значение.The key/value is inserted into the dictionary, and the value is returned.
Ключ отсутствует в словаре.The key is not in the dictionary. valueFactoryсоздает значение.valueFactory generates a value. При valueFactory формировании значения другой поток вставляет значение для ключа.While valueFactory is generating the value, a different thread inserts a value for the key. После valueFactory выполнения и при повторе проверки ключа будет найден ключ, вставленный другим потоком.After valueFactory executes and upon rechecking for the key, the key inserted by the other thread is found. Возвращается значение, вставленное другим потоком.The value inserted by the other thread is returned.

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