简体   繁体   English

在 ConcurrentDictionary AddOrUpdate 中为更新部分添加什么

[英]What to add for the update portion in ConcurrentDictionary AddOrUpdate

I am trying to re-write some code using Dictionary to use ConcurrentDictionary.我正在尝试使用 Dictionary 重写一些代码以使用 ConcurrentDictionary。 I have reviewed some examples but I am still having trouble implementing the AddOrUpdate function.我已经查看了一些示例,但我仍然无法实现 AddOrUpdate function。 This is the original 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 don't know what to add for the update portion:我不知道要为更新部分添加什么:

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

Any pointers would be appreciated.任何指针将不胜感激。

You need to pass a Func which returns the value to be stored in the dictionary in case of an update.您需要传递一个Func以在更新时返回要存储在字典中的值。 I guess in your case (since you don't distinguish between add and update) this would be:我想在你的情况下(因为你不区分添加和更新)这将是:

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

Ie the Func always returns the sessionId, so that both Add and Update set the same value.Func总是返回 sessionId,因此 Add 和 Update 都设置相同的值。

BTW: there is a sample on the MSDN page .顺便说一句: MSDN 页面上有一个示例。

I hope, that I did not miss anything in your question, but why not just like this?我希望,我没有错过您的问题中的任何内容,但是为什么不这样呢? It is easier, atomic and thread-safe (see below).它更容易、原子性和线程安全(见下文)。

userDic[authUser.UserId] = sessionId;

Store a key/value pair into the dictionary unconditionally, overwriting any value for that key if the key already exists: Use the indexer's setter无条件地将键/值对存储到字典中,如果键已经存在,则覆盖该键的任何值:使用索引器的设置器

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

The indexer is atomic, too.索引器也是原子的。 If you pass a function instead, it might not be:如果您通过 function 代替,它可能不是:

All of these operations are atomic and are thread-safe with regards to all other operations on the ConcurrentDictionary.所有这些操作都是原子的,并且对于 ConcurrentDictionary 上的所有其他操作都是线程安全的。 The only caveat to the atomicity of each operation is for those which accept a delegate, namely AddOrUpdate and GetOrAdd.每个操作的原子性唯一需要注意的是那些接受委托的操作,即 AddOrUpdate 和 GetOrAdd。 [...] these delegates are invoked outside of the locks [...] 这些委托是在锁之外调用的

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

I ended up implementing an 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);
    }
}

For those who are interested in, I am currently implementing a case which is a great example for using the "oldValue" aka existing value instead of forcing a new one (personally I don't like the term "oldValue" as it is not that old when it was created just a few processor ticks ago from within a parallel thread).对于那些感兴趣的人,我目前正在实施一个案例,这是使用“oldValue”即现有值而不是强制使用新值的一个很好的例子(我个人不喜欢“oldValue”这个词,因为它不是那个旧时它是在几个处理器滴答之前从并行线程中创建的)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM