ConcurrentDictionary AddOrUpdate

I am trying to rewrite code using a dictionary to use ConcurrentDictionary. I looked at some examples, but I still can not implement the AddOrUpdate function. This is the source code:

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

I do not know what to add for the update part:

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

Any pointers would be appreciated.

+72
c # concurrent-collections
Aug 11 '11 at 15:49
source share
4 answers

You need to pass Func , which returns the value that will be stored in the dictionary in case of updating. I think in your case (since you do not distinguish between add and update) this would be:

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

those. Func always returns sessionId, so both Add and Update set the same value.

BTW: There is a sample on the MSDN page .

+161
Aug 11 '11 at 18:37
source share

I hope I did not miss anything in your question, but why not for nothing? It is simpler, atomic and thread safe (see below).

 userDic[authUser.UserId] = sessionId; 

Store the key / value pair in the dictionary unconditionally, overwriting any value for this key if the key already exists: use the indexer installer

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

The indexer is also atomic. If you pass a function instead, this may not be the case:

All these operations are atomic and are thread safe with respect to all other operations in ConcurrentDictionary. The only caveat against the atomic nature of each operation is for those who accept the delegate, namely AddOrUpdate and GetOrAdd. [...] these delegates go beyond blocking

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

+28
Sep 26 '15 at 10:28
source share

As a result, I used the extension method:

 static class ExtensionMethods { // Either Add or overwrite public static void AddOrUpdate<K, V>(this ConcurrentDictionary<K, V> dictionary, K key, V value) { dictionary.AddOrUpdate(key, value, (oldkey, oldvalue) => value); } } 
+25
Mar 09 '14 at 16:09
source share

For those interested in this, I am currently implementing a case, which is a great example of using "oldValue" as an existing value instead of forcing a new one (I personally don't like the term "oldValue" because it is not so old, when it was created just a few tick processors back from within the parallel thread).

 dictionaryCacheQueues.AddOrUpdate( uid, new ConcurrentQueue<T>(), (existingUid, existingValue) => existingValue ); 
0
Mar 28 '14 at 12:45
source share



All Articles