我有一个映射,其中每个键可以有多个关联值。我认为ConcurrentDictionary可以帮助我更轻松地编写此映射以在多线程环境中使用,但这些方法似乎是围绕单个值构建的。我看到AddOrUpdate()允许我修改值,如果它已经存在,但它不保证该操作的原子性,所以它似乎毫无意义?有没有人有解决这种情况的好策略?
对不起,我想我有点模糊。我想为一个键有多个值,即有一个与键相关联的IList。但我希望能够以安全的方式从多值中添加/删除值。看起来像AddOrUpdate +委托方法如果在同一时间多次调用它会导致事情丢失?
答案 0 :(得分:1)
我认为AddOrUpdate
是原子的,但看起来它对委托来说并不是原子的。遗憾!
可能有用的参考:http://blogs.msdn.com/b/pfxteam/archive/2009/11/06/9918363.aspx
答案 1 :(得分:1)
AddOrUpdate
和TryUpdate
似乎都有效。
修改的
我可能错了。如果是这样,我认为文档不够明确,所以让我们看看代码。礼貌的反射器:
public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
TValue local;
TValue local3;
if (key == null)
{
throw new ArgumentNullException("key");
}
if (addValueFactory == null)
{
throw new ArgumentNullException("addValueFactory");
}
if (updateValueFactory == null)
{
throw new ArgumentNullException("updateValueFactory");
}
do
{
if (!this.TryGetValue(key, out local3))
{
TValue local2;
local = addValueFactory(key);
if (!this.TryAddInternal(key, local, false, true, out local2))
{
continue;
}
return local2;
}
local = updateValueFactory(key, local3);
}
while (!this.TryUpdate(key, local, local3));
return local;
}
现在,如果更新工厂采用现有列表并返回一个带有附加成员的新列表,那么它确实看起来好像它将是原子的。如果出现竞争情况,输家将只是再次调用他们的更新工厂。我错了吗?