Подтвердить что ты не робот

Правильное использование параллельного словаря

Я правильно понимаю, что это правильное использование параллельного словаря

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;

У меня нет замков и т.д., и я просто обновляю значение в словаре, хотя несколько потоков могут пытаться сделать то же самое.

4b9b3361

Ответ 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);
});