Правильное использование параллельного словаря
Я правильно понимаю, что это правильное использование параллельного словаря
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;
У меня нет замков и т.д., и я просто обновляю значение в словаре, хотя несколько потоков могут пытаться сделать то же самое.
Ответы
Ответ 1
Это зависит от того, что вы подразумеваете под потокобезопасностью.
От MSDN - Как добавить и удалить элементы из ConcurrentDictionary:
ConcurrentDictionary<TKey, TValue>
предназначен для многопоточных сценариев. Вам не нужно использовать блокировки в вашем коде для добавления или удаления элементов из коллекции. Тем не менее, всегда возможно, чтобы один поток извлекал значение, а другой поток немедленно обновлял коллекцию, предоставляя тому же ключу новое значение.
Таким образом, можно получить несогласованный вид значения элемента в словаре.
Ответ 2
Лучший способ узнать это - проверить документацию MSDN.
Для ConcurrentDictionary страница http://msdn.microsoft.com/en-us/library/dd287191.aspx
В разделе безопасности потока указано: "Все общедоступные и защищенные члены ConcurrentDictionary (Of TKey, TValue) являются потокобезопасными и могут использоваться одновременно из нескольких потоков".
Итак, с точки зрения concurrency вы в порядке.
Ответ 3
Да, вы правы.
Это и возможность перечислить словарь по одному потоку при его изменении в другом потоке являются единственным средством существования для этого класса.
Ответ 4
Это зависит, в моем случае я предпочитаю использовать этот метод.
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;
});
Ответ 5
Просто примечание: не оправдывает использование объекта ConcurrentDicitonary с линейным циклом, что делает его недоиспользуемым. Лучшая альтернатива - следовать рекомендациям Документации Microsoft, как было упомянуто Одедом с использованием параллелизма, в соответствии с приведенным ниже примером:
Parallel.For(0, 4, i =>
{
myDic.TryAdd(i, 0);
});