你可以使用ConcurrentDictionary进行一对多映射吗?

时间:2010-07-22 17:21:18

标签: c# .net-4.0

我有一个映射,其中每个键可以有多个关联值。我认为ConcurrentDictionary可以帮助我更轻松地编写此映射以在多线程环境中使用,但这些方法似乎是围绕单个值构建的。我看到AddOrUpdate()允许我修改值,如果它已经存在,但它不保证该操作的原子性,所以它似乎毫无意义?有没有人有解决这种情况的好策略?

对不起,我想我有点模糊。我想为一个键有多个值,即有一个与键相关联的IList。但我希望能够以安全的方式从多值中添加/删除值。看起来像AddOrUpdate +委托方法如果在同一时间多次调用它会导致事情丢失?

2 个答案:

答案 0 :(得分:1)

我认为AddOrUpdate是原子的,但看起来它对委托来说并不是原子的。遗憾!

可能有用的参考:http://blogs.msdn.com/b/pfxteam/archive/2009/11/06/9918363.aspx

答案 1 :(得分:1)

AddOrUpdateTryUpdate似乎都有效。

修改

我可能错了。如果是这样,我认为文档不够明确,所以让我们看看代码。礼貌的反射器:

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;
}

现在,如果更新工厂采用现有列表并返回一个带有附加成员的新列表,那么它确实看起来好像它将是原子的。如果出现竞争情况,输家将只是再次调用他们的更新工厂。我错了吗?