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

发布于 2024-11-29 09:10:47 字数 813 浏览 2 评论 0原文

我正在尝试使用 Dictionary 重写一些代码以使用 ConcurrentDictionary。我已经查看了一些示例,但在实现 AddOrUpdate 函数时仍然遇到问题。这是原始代码:

    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;

我不知道要为更新部分添加什么:

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

任何指针将不胜感激。

I am trying to re-write some code using Dictionary to use ConcurrentDictionary. I have reviewed some examples but I am still having trouble implementing the 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

囚你心 2024-12-06 09:10:47

您需要传递一个 Func ,它返回要在更新时存储在字典中的值。我想在您的情况下(因为您不区分添加和更新)这将是:

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

Func 始终返回 sessionId,以便添加和更新都设置相同的值。

顺便说一句:MSDN 页面上有一个示例。

You need to pass a Func which returns the value to be stored in the dictionary in case of an update. 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);

I.e. the Func always returns the sessionId, so that both Add and Update set the same value.

BTW: there is a sample on the MSDN page.

遥远的绿洲 2024-12-06 09:10:47

我希望我没有错过你问题中的任何内容,但为什么不就这样呢?它更简单、原子且线程安全(见下文)。

userDic[authUser.UserId] = sessionId;

无条件地将键/值对存储到字典中,如果该键已存在,则覆盖该键的任何值:使用索引器的setter

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

索引器也是原子的。如果您传递一个函数,它可能不是:

所有这些操作都是原子操作,并且相对于 ConcurrentDictionary 上的所有其他操作来说都是线程安全的。对于每个操作的原子性,唯一需要注意的是那些接受委托的操作,即 AddOrUpdate 和 GetOrAdd。 [...]这些委托在锁之外被调用

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

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)

The indexer is atomic, too. If you pass a function instead, it might not be:

All of these operations are atomic and are thread-safe with regards to all other operations on the ConcurrentDictionary. The only caveat to the atomicity of each operation is for those which accept a delegate, namely AddOrUpdate and GetOrAdd. [...] these delegates are invoked outside of the locks

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

苍白女子 2024-12-06 09:10:47

我最终实现了一个扩展方法:

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

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);
    }
}
濫情▎り 2024-12-06 09:10:47

对于那些感兴趣的人,我目前正在实现一个案例,这是使用“oldValue”又名现有值而不是强制使用新值的一个很好的例子(我个人不喜欢“oldValue”一词,因为它不是那个)旧的,当它是在几个处理器时钟周期前从并行线程内创建的)。

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

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).

dictionaryCacheQueues.AddOrUpdate(
    uid,
    new ConcurrentQueue<T>(),
    (existingUid, existingValue) => existingValue
);
献世佛 2024-12-06 09:10:47

最简单的 2023 年解决方案,无需引入额外的新变量:

userDic.AddOrUpdate(authUser.UserId,
                    a.Session.SessionID.ToString(),
                    (_, _) => a.Session.SessionID.ToString());

尽情享受!

PS:了解丢弃变量在 MSDN 上。

Easiest 2023 solution without introducing additional new variables:

userDic.AddOrUpdate(authUser.UserId,
                    a.Session.SessionID.ToString(),
                    (_, _) => a.Session.SessionID.ToString());

Enjoy!

PS: learn about the discard variable on MSDN.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文