我有这个代码,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
完全相同(从文件中读取)。
添加断点时,这种情况永远不会发生。
我的怀疑是某种迟到的评价。
为什么会发生这种情况的想法?并防止它?
答案 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...
}