ConcurrentDictionary AddOrUpdate

J’essaie de ré-écrire du code en utilisant Dictionary pour utiliser ConcurrentDictionary. J’ai examiné quelques exemples, mais j’ai toujours du mal à implémenter la fonction AddOrUpdate. Ceci est le code original:

dynamic a = HttpContext; Dictionary userDic = this.HttpContext.Application["UserSessionList"] as Dictionary; if (userDic != null) { if (useDic.ContainsKey(authUser.UserId)) { userDic.Remove(authUser.UserId); } } else { userDic = new Dictionary(); } userDic.Add(authUser.UserId, a.Session.SessionID.ToSsortingng()); this.HttpContext.Application["UserDic"] = userDic; 

Je ne sais pas quoi append pour la partie mise à jour:

 userDic.AddOrUpdate(authUser.UserId, a.Session.SessionID.ToSsortingng(), /*** what to add here? ***/); 

Tout pointeur serait apprécié.

Vous devez passer un Func qui renvoie la valeur à stocker dans le dictionnaire en cas de mise à jour. Je suppose que dans votre cas (puisque vous ne faites pas la distinction entre append et mettre à jour) ce serait:

 var sessionId = a.Session.SessionID.ToSsortingng(); userDic.AddOrUpdate( authUser.UserId, sessionId, (key, oldValue) => sessionId); 

C’est-à-dire que le Func renvoie toujours le sessionId, de sorte que Add et Update définissent la même valeur.

BTW: il y a un exemple sur la page MSDN .

J’espère que je n’ai rien manqué dans votre question, mais pourquoi pas comme ça? C’est plus facile, atomique et thread-safe (voir ci-dessous).

 userDic[authUser.UserId] = sessionId; 

Stocker une paire clé / valeur dans le dictionnaire sans condition, en remplaçant toute valeur pour cette clé si celle-ci existe déjà: Utiliser le setter de l’indexeur

(Voir: http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx )

L’indexeur est également atomique. Si vous passez une fonction à la place, cela pourrait ne pas être:

Toutes ces opérations sont atomiques et sont compatibles avec toutes les autres opérations sur le ConcurrentDictionary. La seule mise en garde concernant l’atomicité de chaque opération concerne ceux qui acceptent un délégué, à savoir AddOrUpdate et GetOrAdd. […] ces delegates sont appelés en dehors des serrures

Voir: http://blogs.msdn.com/b/pfxteam/archive/2010/01/08/9945809.aspx

J’ai fini par implémenter une méthode d’extension:

 static class ExtensionMethods { // Either Add or overwrite public static void AddOrUpdate(this ConcurrentDictionary dictionary, K key, V value) { dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value); } } 

Pour ceux qui sont intéressés, je suis en train d’implémenter un cas qui est un excellent exemple pour utiliser la valeur “aka” de oldValue au lieu d’en imposer une nouvelle (personnellement je n’aime pas le terme “oldValue” car ce n’est pas ça) vieux quand il a été créé juste un peu de processeur coche depuis un fil parallèle).

 dictionaryCacheQueues.AddOrUpdate( uid, new ConcurrentQueue(), (existingUid, existingValue) => existingValue );