it-swarm.com.ru

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

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

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;

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

72
Jon

Это зависит от того, что вы подразумеваете под потокобезопасностью.

Из MSDN - Как: добавлять и удалять элементы из ConcurrentDictionary :

ConcurrentDictionary<TKey, TValue> предназначен для многопоточных сценариев. Вам не нужно использовать блокировки в своем коде для добавления или удаления элементов из коллекции. Однако один поток всегда может извлечь значение, а другой поток - немедленно обновить коллекцию, дав этому же ключу новое значение.

Таким образом, можно получить противоречивое представление значения элемента в словаре.

66
Oded

Лучший способ узнать это - проверить документацию MSDN.

Для ConcurrentDictionary страница http://msdn.Microsoft.com/en-us/library/dd287191.aspx

В разделе безопасности потоков указано: "Все открытые и защищенные члены ConcurrentDictionary (Of TKey, TValue) являются потокобезопасными и могут использоваться одновременно из нескольких потоков".

Так что с точки зрения параллелизма у вас все в порядке.

4
Erdem

Да ты прав.

Это и возможность перечислить словарь в одном потоке при его изменении в другом потоке - единственные средства существования этого класса.

2
Jan

Это зависит, в моем случае, я предпочитаю использовать этот метод.

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;
  });
1
Onur

Просто примечание: не оправдывает использование объекта ConcurrentDicitonary с линейным циклом, что делает его недоиспользуемым. Лучшая альтернатива - следовать рекомендациям Документации Microsoft, как указано Oded с использованием Parallelism, в соответствии с приведенным ниже примером:

Parallel.For(0, 4, i => 
{
   myDic.TryAdd(i, 0);
});
0
Antonio Leonardo