.NET Dictionary对象是否可能溢出?

时间:2012-07-06 19:02:05

标签: .net dictionary overflow

我现在有一个事件处理器类,它有一个Dictionary来存储所有订阅。实际上它是一本字典词典。此进程类与第三方远程服务器通信以发出对目标数据的请求。我问这个问题,因为现在我们正在经历一些偶尔订阅丢失的问题。由于某些原因很难验证这种丢失是否发生在与远程服务器的连接中,我现在必须首先检查我的事件处理器类是否有任何问题。我的第一个疑问是,如果订阅信息由于此Dictionary对象的溢出而丢失。有谁有想法吗?谢谢!

更新

也许我应该多谈一下这个场景,因为代码不容易显示。我们曾经使用B的供应商提供的API,将我们的旧SW(我们称之为A)与远程数据服务(称为B)进行通信。但是,由于我们将A更改为64位SW,但为B提供的库仍为32位,因此我们的新64位A不能再使用此库。所以我正在设计一个名为C的32位SW,使用该库连接到B,同时使用WCF保持与64位A的通信。由于C主要是一个pub / sub结构,正如我之前提到的,我使用Dictionary of Dictionary来维护C中的请求和订阅。这就是我们的问题:我们遇到了一些订阅丢失(很长时间没有发布,但在重新初始化订阅后,我们可以在A处获得出版物。我们不容易检查B的反馈,看看是否存在任何错误配置。我的WCF服务日志也没有显示任何错误。我不得不怀疑这个问题只发生在C语言上。我知道多线程问题所以我已经锁定了Dictionary的每个操作。但我想不出什么可能是错的。顺便说一下,它不像C,内存耗尽,C崩溃了。

2 个答案:

答案 0 :(得分:6)

如果“溢出”是指“默默地意外丢失数据”,那么不是,不是我所知道的。

如果你的意思是“耗尽系统中的所有内存,直到它崩溃”,那么是的,这是可能的,但这听起来不像你发生的事情。

如果您在没有任何锁定的情况下使用来自多个线程的标准Dictionary<,>,那么 可能会导致您丢失数据。如果您使用的是.NET 4,则应该使用锁定(小心!)或使用ConcurrentDictionary<,>

此外,如果你有任何你没想到的重复密钥,那么如果使用索引器,那么<​​em>覆盖一个条目的数据与另一个条目。 (如果使用Add方法则不会 - 它会抛出异常。

基本上我们猜测直到我们看到一些代码或至少获得更多上下文...

答案 1 :(得分:2)

听起来像是竞争条件。

您可能有一些看起来像这样的代码:

if (!myDictionary.ContainsKey(key))
{
  //point of interest
  myDictionary[key] = new Dictionary<X, Y>()
}
myDictionary[key][innerkey] = innnervalue;

问题在于两个线程使其成为条件下的兴趣点注释。你不打算为同一个键运行那个块两次,但是线程魔法会让它发生。

  1. 主题A和主题B使其达到兴趣点。
  2. 线程A唤醒并运行该方法的其余部分。
  3. 线程B唤醒并运行,孤立线程A创建的字典。
  4. 您可以通过保护锁定后的共享实例来解决此问题:

    lock(_theLockInstance)
    {
      if (!myDictionary.ContainsKey(key))
      {
        //point of interest
        myDictionary[key] = new Dictionary<X, Y>()
      }
      myDictionary[key][innerkey] = innnervalue;
    }
    

    现在,一次只有一个线程可以到达临界区,并且不会创建孤立词典。