ConcurrentDictionary<TKey,TValue>
和 Interlocked.Exchange<T>(...)
的数据结构允许您自动设置新值并检索分配给任意键的旧值?任何 AddOrUpdate(...)
重载似乎都不可能。
此功能不包含在开箱即用中。 GitHub dotnet/runtime 存储库中存在针对 API 提案,它将提供此功能,但目前还没有产生太大的吸引力。不过,您可以使用基本的
TryGetValue
手动实现它
、TryAdd
和 TryUpdate
方法:
public static TValue AddOrUpdate<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> source,
TKey key,
Func<TKey, TValue> addValueFactory,
Func<TKey, TValue, TValue> updateValueFactory,
out bool oldValueExists,
out TValue oldValue) where TKey : notnull
{
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(addValueFactory);
ArgumentNullException.ThrowIfNull(updateValueFactory);
while (true)
{
if (source.TryGetValue(key, out oldValue))
{
TValue newValue = updateValueFactory(key, oldValue);
if (source.TryUpdate(key, newValue, oldValue))
{
oldValueExists = true;
return newValue;
}
}
else
{
TValue newValue = addValueFactory(key);
if (source.TryAdd(key, addValueFactory(key)))
{
oldValueExists = false;
oldValue = default;
return newValue;
}
}
}
}
AddOrUpdate
实现的修改版本。