刚开始用C#的线程写程序,碰着个关于锁的奇怪问题。望高人指教。一个程序有两个线程。
先是一个公共的 ArrayList list. 里面有很多的元素(是比较复杂的类实例)线程A
不定时 的向这个list中插入元素。线程B
每时间间隔遍历list中的元素输出。基本代码如下。{
while(true)
lock(list)
{
foreach(aClass aa in list)
{
name = aa.name;
}
Thread.Sleep(500);
}
}我在测试的时候,让A线程向list插入1000个元素。结果就偶尔会在B线程中报出foreach的错误,说是在遍历的时候,list已经被修改???!!!这是怎么回事??? 我已经加锁的啊 ??完全茫然,望达人指教。多谢。ps:新人一个,没啥分,只能期盼好心的人了
先是一个公共的 ArrayList list. 里面有很多的元素(是比较复杂的类实例)线程A
不定时 的向这个list中插入元素。线程B
每时间间隔遍历list中的元素输出。基本代码如下。{
while(true)
lock(list)
{
foreach(aClass aa in list)
{
name = aa.name;
}
Thread.Sleep(500);
}
}我在测试的时候,让A线程向list插入1000个元素。结果就偶尔会在B线程中报出foreach的错误,说是在遍历的时候,list已经被修改???!!!这是怎么回事??? 我已经加锁的啊 ??完全茫然,望达人指教。多谢。ps:新人一个,没啥分,只能期盼好心的人了
lock( list.SyncRoot )
{
//插入数据
}lock( list.SyncRoot )
{
//遍历集合
}
你这里的 list 对象是在什么地方创建的?
list的定义 public List<DTUClient> logicalDUTList = new List<DTUClient>();没找到有SyncRoot这个属性还是我理解有误??
最好换成
if(list.items.count>0)
{
//取出一个
//执行代码
}
还能接到分么?lock(list)
{
foreach(aClass aa in list)
{
name = aa.name;
}
Thread.Sleep(500);
}
把Thread.Sleep放在里面?是什么用意?别的获得索的机会有多少?是不是应该放在外面?
范型里没有SyncRoot
你可以使用ReaderWriterLock
lock( list.SyncRoot )
{
//插入数据
Monitor.Pulse(list.SyncRoot );
} lock( list.SyncRoot )
{
Monitor.Wait(list.SyncRoot );
//遍历集合
}