GetOrAdd
GetOrAdd у
ConcurrentDictionary
не затирает существующее значение.
При споре потоков фабрика может выполниться
несколько раз, в словарь попадёт один результат.
В однопоточном примере фабрика вызывается
один раз. Тип безопасен для нескольких потоков.
Синтаксис
TValue value = map.GetOrAdd(key, addValue);
TValue value = map.GetOrAdd(key, k => createValue);
Пример
Давайте вызвать GetOrAdd дважды:
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> map =
new ConcurrentDictionary<string, int>();
int first = map.GetOrAdd("abcde", 1);
int second = map.GetOrAdd("abcde", 2);
Console.WriteLine(first);
Console.WriteLine(second);
}
}
Результат выполнения кода:
1
1
Пример
Давайте использовать фабрику:
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> map =
new ConcurrentDictionary<string, int>();
int calls = 0;
int res = map.GetOrAdd("abcde", key =>
{
calls++;
return 1;
});
map.GetOrAdd("abcde", key =>
{
calls++;
return 2;
});
Console.WriteLine(res);
Console.WriteLine(calls);
}
}
Результат выполнения кода:
1
1
Пример
Давайте прочитать значение после двух вызовов:
using System;
using System.Collections.Concurrent;
class Program
{
static void Main()
{
ConcurrentDictionary<string, int> map =
new ConcurrentDictionary<string, int>();
map.GetOrAdd("abcde", 1);
map.GetOrAdd("abcde", 2);
int res = map["abcde"];
Console.WriteLine(res);
}
}
Результат выполнения кода:
1
Смотрите также
-
AddOrUpdate,
с обновлением -
TryAdd,
без чтения -
индексатор,
прямой доступ -
ConcurrentDictionary,
класс словаря