Можете ли вы использовать ConcurrentDictionary для сопоставления один ко многим? - PullRequest
4 голосов
/ 22 июля 2010

У меня есть сопоставление, где каждый ключ может иметь несколько связанных значений. Я думал, что ConcurrentDictionary мог бы помочь мне легче кодировать эту карту для использования в многопоточной среде, но методы, кажется, построены вокруг единственного значения. Я вижу, что AddOrUpdate () позволяет мне изменить значение, если оно уже существует, но это не гарантирует атомарность для этой операции, так что это кажется бессмысленным? У кого-нибудь есть хорошая стратегия для решения этой ситуации?

Извините, я думаю, я был немного расплывчатым. Я хотел бы иметь несколько значений для ключа, т.е. иметь IList, связанный с ключом. Но я хочу иметь возможность добавлять / удалять значения из мульти-значения безопасным способом. Похоже, что метод AddOrUpdate + делегат может привести к потере чего-либо, если несколько вызовов к нему будут сделаны в одно и то же время?

Ответы [ 2 ]

1 голос
/ 22 июля 2010

Похоже, что и 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;
}

Теперь, если фабрика обновлений взяла существующий список и возвратила новый с дополнительным элементом, мне действительно кажется, что он будет атомарным. В случае состояния гонки проигравшему просто будет снова вызвана их фабрика обновлений. Я ошибаюсь?

1 голос
/ 22 июля 2010

Я думал, что AddOrUpdate был атомарным, но похоже, что он не атомарен по отношению к делегату. Извините! * * 1002

Ссылка, которая может помочь: http://blogs.msdn.com/b/pfxteam/archive/2009/11/06/9918363.aspx

...