C#迟到评估会导致Dictionary.Add()出现意外结果

时间:2014-06-12 12:03:07

标签: c# dictionary lazy-loading

我有这个代码,TheData是一个包含3个项目的集合:

ICollection<Thread> threads = new List<Thread>();
foreach (CData data in TheData) 
{
   Thread t = new Thread(DoSomething);
   threads.Add(t);
   t.Start(data);
}

foreach (var thread in threads)
   thread.Join();

DoSomething方法:

static void OpenConnections(CData deviceData)
{

   CDevice deviceInstance = new CDevice((EDeviceType)Enum.Parse(typeof(EDeviceType), deviceData.Type));
   m_deviceManager.AddDevice(deviceInstance);

   // More stuff...
}

到目前为止一切顺利。

m_deviceManager.AddDevice,将新项添加到内部字典中。

在大多数执行中,在Join行之后,m_deviceManager字典具有预期的所有3个值。

问题是在某些执行中,在Join行之后,m_deviceManager字典有3个值,但其中一些是null ...

每次

TheData完全相同(从文件中读取)。 添加断点时,这种情况永远不会发生。 我的怀疑是某种迟到的评价。 为什么会发生这种情况的想法?并防止它?

1 个答案:

答案 0 :(得分:2)

字典不是线程安全的,因此您必须同步对它的访问,以便一次只有一个线程可以使用它。

常见的方法是创建一个专门用作锁的标识符的对象。这应该与您保护的数据具有相同的生命周期,因此如果m_deviceMananger是静态的,它也应该是:

private static object m_sync = new Object();

现在你可以锁定访问字典的代码:

static void OpenConnections(CData deviceData) {

   CDevice deviceInstance = new CDevice((EDeviceType)Enum.Parse(typeof(EDeviceType), deviceData.Type));
   lock (m_sync) {
      m_deviceManager.AddDevice(deviceInstance);
   }

   // More stuff...
}