有没有一种类似于ConcurrentDictionary<TKey,TValue>
和Interlocked.Exchange<T>(...)
的数据 struct ,可以让你原子地设置一个新值,并检索分配给任意键的旧值?AddOrUpdate(...)
个过载都不可能.
有没有一种类似于ConcurrentDictionary<TKey,TValue>
和Interlocked.Exchange<T>(...)
的数据 struct ,可以让你原子地设置一个新值,并检索分配给任意键的旧值?AddOrUpdate(...)
个过载都不可能.
此功能不包括在开箱即用中.GitHub DotNet/Runtime存储库中存在Transact
方法的API proposal,这将提供此功能,但目前还没有产生太大的吸引力.不过,您可以使用基本的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
实现的修改版本.