【问题标题】:Do I need a ConcurrentDictionary? Will regular Dictionary do?我需要并发字典吗?请问普通字典可以吗?
【发布时间】:2016-06-15 19:33:10
【问题描述】:

我目前正在使用ConcurrentDictionary 来保存已通过我的 API 进行身份验证的登录名集合。我这样做是为了防止来自其他 Web 客户端的重复登录(系统架构的要求)。如果用户使用已经“登录”的登录名进行身份验证,他们可以选择......

  1. 继续,之前的登录将失效
  2. 取消,当前会话将被注销

我正在使用ConcurrentDictionary,因为它应该是线程安全的,这在多个客户端访问 API 的环境中很重要。

我要问的是是否需要 ConcurrentDictionary,因为我在删除集合中与给定键匹配的所有项目时遇到了麻烦。在这种情况下是否需要ConcurrentDictionary?如果没有,那么简单的Dictionary 就足够了吗?如果没有,并且需要ConcurrentDictionary,是否有一种方法可以删除与给定键匹配的所有条目?我只能看到TryRemove(),它似乎只删除了一个条目。

【问题讨论】:

  • 只能有一个条目与ConcurrentDictionary 中的键匹配。
  • 我的意思不是不尊重,但你的身份验证方法让我担心。像 web-api 这样的 Web 技术注定是无状态的。您不应该跟踪谁在内存中登录。我会完全重新考虑身份验证/授权过程。可能查一些现有的框架和例子,有很多。
  • @Lee - 我什至没有意识到这一点。也许这就是为什么没有方法可以全部删除的原因。
  • @Igor - 我很不同意你的看法。 API 可以是你需要的任何东西。它似乎对我们很有效。
  • @webworm,不,标准字典不是线程安全的

标签: c# asp.net-web-api concurrentdictionary


【解决方案1】:

直接回答你的问题:

是的,您需要ConcurrentDictionary。您正在跨多个线程共享状态。

请记住,字典的每个键都有一个条目。这就是 Dictionary 的定义,ConcurrentDictionary 不会改变这一点。

下面是对您的要求的更全面和更完整的答案。


整个解决方案是短视的,因为您与会话基础设施没有任何联系,无法知道用户的会话何时超时并​​有效地导致他们被注销。此外,如果您考虑部署到启动新实例的云平台,则无需与您的应用的其他实例进行协调。

换句话说,您将自己置于一个在不破坏此功能的情况下很难扩展您的应用程序的境地。

处理单个会话要求的最可靠的方法之一可能是使用您的数据库:

  • 有一个字段来跟踪您的用户在登录时的最后一个会话 ID。
  • 添加session listener 以在会话超时时清除该字段
  • 如果会话 ID 与字段中的不同,则表明您有新的登录尝试。
  • 如果您需要完全控制会话 ID,请提供您自己的 session id manager(可能需要在其中包含编码的服务器 ID)。

您会发现该要求比表面上听起来要复杂得多。你不能像网络空间中的桌面应用程序那样思考——这正是这个要求的来源。

【讨论】:

  • 甚至不是我要问的问题。问题是关于 ConcurrentDictionary。
  • 并发字典是错误的答案。但是,如果它保持共享状态,它比标准字典要好。
  • 我同意@BerinLoritsch。如果服务器重置,用户的登录凭据可能仍然有效,但现在您不会知道它,因为您的字典是空的。如果您计划通过提供跨多个主机的负载平衡来扩展您的应用程序,那么一台主机上的字典(并发或非并发)将看不到另一台主机上的字典。当然,您可以强制用户返回同一服务器,但是,从架构上讲,字典和并发字典是错误的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多