我对
AddOrUpdate
方法感到困惑。文档特别说updateValueFactory
不同步。
MSDN 中给出了这个例子:
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);
});
如果有多个线程尝试增加
oldvalue
,那么其中一些线程是否可能会更新过时的值?
谢谢。
如果有多个线程尝试增加旧值,那么其中一些线程是否可能会更新过时的值?
不。仅当没有其他线程同时更新该值时,
updateValueFactory
返回的值才会存储在字典中。否则,如果值已更改,则会再次调用 updateValueFactory
,并以新的当前值作为参数。 updateValueFactory
会根据需要多次调用,直到当前线程赢得更新字典的乐观竞赛。
下面显示了如何将
AddOrUpdate
实现为扩展方法,以防它本身不可用:
public static TValue AddOrUpdate<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> source,
TKey key,
TValue addValue,
Func<TKey, TValue, TValue> updateValueFactory)
{
ArgumentNullException.ThrowIfNull(source);
ArgumentNullException.ThrowIfNull(updateValueFactory);
while (true)
{
if (source.TryGetValue(key, out TValue existingValue))
{
TValue newValue = updateValueFactory(key, existingValue);
if (source.TryUpdate(key, newValue, existingValue)) return newValue;
}
else
{
if (source.TryAdd(key, addValue)) return addValue;
}
// We lost the race. Let's try again.
}
}