Правильно ли я считаю, что это правильное использование параллельного словаря
private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>();
//Main thread at program startup
for(int i = 0; i < 4; i++)
{
myDic.Add(i, 0);
}
//Seperate threads use this to update a value
myDic[InputID] = newLongValue;
У меня нет блокировок и т. Д., И я просто обновляю значение в словаре, хотя несколько потоков могут пытаться сделать то же самое.
newLongValue
зависит от предыдущего значенияmyDic[InputID]
?myDic[InputID]
за состояния гонки. Вы должны попробоватьGetOrAdd
myDic[InputID]
вызывает какие-либо проблемы, когда он используется в качестве lvalue.GetOrAdd
не является правильной заменой, поскольку добавляет, только если значение не существует. Вместо этого мы можем использоватьAddOrUpdate
для добавления / обновления того же значения в словаре.Ответы:
Это зависит от того, что вы подразумеваете под потокобезопасностью.
Из MSDN - Как: добавлять и удалять элементы из ConcurrentDictionary :
Таким образом, можно получить противоречивое представление о значении элемента в словаре.
источник
Лучший способ узнать это - проверить документацию MSDN.
Для ConcurrentDictionary страница http://msdn.microsoft.com/en-us/library/dd287191.aspx
В разделе, посвященном безопасности потоков, говорится: «Все открытые и защищенные члены ConcurrentDictionary (Of TKey, TValue) являются потокобезопасными и могут использоваться одновременно из нескольких потоков».
Так что с точки зрения параллелизма все в порядке.
источник
Да ты прав.
Это и возможность перечислить словарь в одном потоке при изменении его в другом потоке - единственные средства существования для этого класса.
источник
ConcurrentDictionary
.В зависимости от обстоятельств, в моем случае я предпочитаю использовать этот метод.
ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);
См. Библиотеку MSDN об использовании метода .
Пример использования:
results.AddOrUpdate( Id, id => new DbResult() { Id = id, Value = row.Value, Rank = 1 }, (id, v) => { v.Rank++; return v; });
источник
Просто примечание: не оправдывает использование объекта ConcurrentDicitonary с линейным циклом, что делает его малоиспользуемым. Лучшая альтернатива - следовать рекомендациям документации Microsoft, упомянутым Одедом с использованием параллелизма, в соответствии с приведенным ниже примером:
Parallel.For(0, 4, i => { myDic.TryAdd(i, 0); });
источник