我有一些代码,使用
GetOrAdd
中的 ConcurrentDictionary
函数将带有唯一密钥的值添加到持有者中。但是,我希望能够判断是否找到了值键(即从 true
返回的 TryGet
)或者是否必须添加它。
我在网上找不到任何表明这是可以实现的东西,所以如果有人有任何想法,那将会非常有帮助。
不一致,不。如果该方法返回的值不是您提供的值,那么您就知道该键已经存在,但如果该键存在并且具有与您提供的值相同的值,则不会有任何区别。如果您想确切地知道,那么您必须首先测试密钥。听起来您最好的选择是先致电
ContainsKey
,然后再致电 GetOrAdd
。您可以将其包装到您自己的单个方法中,这样如果您需要它是原子的,就可以轻松重用和锁定字典。
这是我的无锁尝试。如果在调用时没有这样的键,则
GetOrAdd
可以调用委托,但如果另一个线程获胜,最终可能会放弃返回。这个想法是在 lambda 内部创建一个新对象,然后将其与 GetOrAdd
返回的内容进行比较(如果它是作为“Add”启动的),以减少比较开销。它尚未被证明是可靠的,但对我来说看起来是原子的和高性能的。
我把它作为扩展:
public static class ConcurrentDictionaryExtensions
{
public static bool TryGetOrAdd<TKey, TValue>(
this ConcurrentDictionary<TKey, TValue> dictionary,
TKey key,
out TValue resultingValue) where TValue : class, new()
{
bool added = false;
TValue newValue = null;
resultingValue = dictionary.GetOrAdd(key, _ => {
newValue = new TValue();
added = true; // Indicate that a new object is being created.
return newValue;
});
return added ? ReferenceEquals(resultingValue, newValue) : false;
}
}
用途:
bool isNew = myDictionary.TryGetOrAdd(1, out var resultingValue);