我有一个简单的场景,我想更新现有项目的值。只有AddOrUpdate方法提供了一个委托,我可以在其中更新旧值。但是,如果密钥不存在,我不想添加任何内容。TryUpdate方法也没有我可以获得旧值的重载。有没有办法用当前的 API 做到这一点?
这是我正在寻找的签名:
bool TryUpdate(TKey key, Func<TValue,TValue> updateValueFactory)
我有一个简单的场景,我想更新现有项目的值。只有AddOrUpdate方法提供了一个委托,我可以在其中更新旧值。但是,如果密钥不存在,我不想添加任何内容。TryUpdate方法也没有我可以获得旧值的重载。有没有办法用当前的 API 做到这一点?
这是我正在寻找的签名:
bool TryUpdate(TKey key, Func<TValue,TValue> updateValueFactory)
您必须准备好循环并且可能Func
不止一次调用(与GetOrAdd
使用 one 的重载相同)。这意味着如果它Func
有副作用,它不会从外部看起来是原子的。真的,Func
s 不应该有副作用,但它们总是有一些成本,所以重复调用的可能性不容忽视:
public static bool TryUpdate<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> dict,
TKey key,
Func<TValue, TValue> updateFactory)
{
TValue curValue;
while(dict.TryGetValue(key, out curValue))
{
if(dict.TryUpdate(key, updateFactory(curValue), curValue))
return true;
// if we're looping either the key was removed by another thread,
// or another thread changed the value, so we start again.
}
return false;
}
如前所述,因为它可以循环,所以如果Func
.
(编辑:删除一个潜在的捷径,该捷径确实太令人担忧而无法普遍使用,并且可能会咬到尝试过的人)。