.NET 并发字典交换值

Kyl*_*lan 5 .net c# collections concurrency concurrentdictionary

是否有类似于ConcurrentDictionary<TKey,TValue>和的数据结构Interlocked.Exchange<T>(...),它允许您自动设置新值并检索分配给任意键的旧值?任何超载似乎都不可能AddOrUpdate(...)

The*_*ias 5

此功能不包含在开箱即用中。GitHub dotnet/runtime 存储库中存在一个方法的API 提案Transact,该提案将提供此功能,但目前尚未产生太大的吸引力。不过,您可以使用基本的TryGetValue,TryAddTryUpdate方法手动实现它:

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上述实现是现有实现的修改版本AddOrUpdate