web-dev-qa-db-fra.com

Utilisation concordante du dictionnaire simultané

Ai-je raison de penser que c'est l'utilisation correcte d'un dictionnaire simultané

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;

Je n'ai pas de verrou, etc. et je ne fais que mettre à jour la valeur dans le dictionnaire, même si plusieurs threads tentent de faire de même.

74
Jon

Cela dépend de ce que vous entendez par thread-safe.

De MSDN - Comment: ajouter et supprimer des éléments d'un ConcurrentDictionary :

ConcurrentDictionary<TKey, TValue> est conçu pour les scénarios multithread. Vous n'êtes pas obligé d'utiliser des verrous dans votre code pour ajouter ou supprimer des éléments de la collection. Cependant, il est toujours possible pour un thread de récupérer une valeur et un autre pour mettre immédiatement à jour la collection en attribuant une nouvelle valeur à la même clé.

Ainsi, il est possible d’obtenir une vue incohérente de la valeur d’un élément du dictionnaire.

67
Oded

Le meilleur moyen de le savoir est de consulter la documentation MSDN.

Pour ConcurrentDictionary, la page est http://msdn.Microsoft.com/en-us/library/dd287191.aspx

Dans la section relative à la sécurité des threads, il est indiqué "Tous les membres publics et protégés de ConcurrentDictionary (Of TKey, TValue) sont thread-safe et peuvent être utilisés simultanément à partir de plusieurs threads".

Donc, du point de vue de la concurrence, tout va bien.

4
Erdem

Oui, tu as raison.

Cela et la possibilité d'énumérer le dictionnaire sur un thread tout en le modifiant sur un autre thread sont le seul moyen d'existence de cette classe.

2
Jan

Cela dépend, dans mon cas, je préfère utiliser cette méthode.

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);

Voir MSDN Library pour plus de détails sur l’utilisation de la méthode.

Exemple d'utilisation:

results.AddOrUpdate(
  Id,
  id => new DbResult() {
     Id = id,
     Value = row.Value,
     Rank = 1
  },
  (id, v) =>
  {
     v.Rank++;
     return v;
  });
1
Onur

Juste une remarque: Ne justifie pas l'utilisation d'un objet ConcurrentDicitonary avec une boucle linéaire, ce qui le rend sous-utilisé. La meilleure alternative est de suivre les recommandations de la documentation Microsoft, comme indiqué par Oded en utilisant le parallélisme, selon l'exemple ci-dessous:

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