【求助】集合已修改 可能无法执行枚举操作.

yang1216 2014-10-11 10:34:34
各位老师,我遇到了一个可能是多线程的问题,大家帮忙看看好吗。

主线程UI,然后一个timer线程
timer线程调用SOCKET通讯程序,然后保存数据库,然后invoke主线程刷新界面

void threadTimerCallback(object obj)
{
if(this.InvokeRequired)
{
comm.poll();//通讯
foreach(var stationRecord in comm.data)
{
db.add(stationRecord);
lstRecord[stationRecord.StationId]=stationRecord;
}
BeginInvoke(new EventHandler(RunOnWorkerThread),nulll);
}
}
void RunOnWorkerThread(object sender,EventArgs e)
{
WindowRefresh(lstRecord);//更新界面
}

现在运行一段时间以后就会报错,在第一个函数的foreach那里,说是 集合已修改 可能无法执行枚举操作.
我知道foreach里面不能修改集合,可是我这里也没有修改呀。comm.data唯一修改的地方就是comm.poll(),在枚举外面。其他地方也就是用一下lstRecord的数据,绝对没有修改。

非常感谢。
...全文
311 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
exception92 2014-10-11
  • 打赏
  • 举报
回复
引用 7 楼 yang1216 的回复:
[quote=引用 5 楼 duanzi_peng 的回复:] comm.data 是什么类型的??可以在foreach之前 把 comm.data 赋值给一个新的集合变量,然后遍历这个集合变量;
是Dictionary<int,byte[]>[/quote] Dictionary<int,byte[]> dicTempList = new Dictionary<int,byte[]>(comm.data); foreach(var stationRecord in dicTempList ){ } 这样修改一下。
yang1216 2014-10-11
  • 打赏
  • 举报
回复
引用 6 楼 Z65443344 的回复:
[quote=引用 3 楼 yang1216 的回复:] [quote=引用 1 楼 Z65443344 的回复:] 右键,查找所有引用,看到底其他地方使用使用了这个集合 此外,db.add也是有可能会出问题的 db这个对象,两个线程在用,一个往里add,另一个循环取出来remove 这个要加lock啊
db其实是sqlhelper之类的东西,这就是insert函数而已。没有删除操作。 我试试lock吧。[/quote] 知道了,add不过是你自己随便取的方法名,根本跟集合操作无关是吧. 那就先不要加lock了,跟这个应该无关.[/quote] 对对,完全可以理解成sqlhelper.insert(record);
yang1216 2014-10-11
  • 打赏
  • 举报
回复
引用 5 楼 duanzi_peng 的回复:
comm.data 是什么类型的??可以在foreach之前 把 comm.data 赋值给一个新的集合变量,然后遍历这个集合变量;
是Dictionary<int,byte[]>
於黾 2014-10-11
  • 打赏
  • 举报
回复
引用 3 楼 yang1216 的回复:
[quote=引用 1 楼 Z65443344 的回复:] 右键,查找所有引用,看到底其他地方使用使用了这个集合 此外,db.add也是有可能会出问题的 db这个对象,两个线程在用,一个往里add,另一个循环取出来remove 这个要加lock啊
db其实是sqlhelper之类的东西,这就是insert函数而已。没有删除操作。 我试试lock吧。[/quote] 知道了,add不过是你自己随便取的方法名,根本跟集合操作无关是吧. 那就先不要加lock了,跟这个应该无关.
exception92 2014-10-11
  • 打赏
  • 举报
回复
comm.data 是什么类型的??可以在foreach之前 把 comm.data 赋值给一个新的集合变量,然后遍历这个集合变量;
yang1216 2014-10-11
  • 打赏
  • 举报
回复
引用 2 楼 caozhy 的回复:
如果上一个timer没有执行完,又到了时间点,那么会再开一个线程,所以可能timer线程不止一个,你需要同步所有的公有变量。
谢谢。 请教,有啥办法知道这种情况出现了吗。我的程序对时间要求很高,我想知道是不是真的一个interval时间不能执行完所有任务。
yang1216 2014-10-11
  • 打赏
  • 举报
回复
引用 1 楼 Z65443344 的回复:
右键,查找所有引用,看到底其他地方使用使用了这个集合 此外,db.add也是有可能会出问题的 db这个对象,两个线程在用,一个往里add,另一个循环取出来remove 这个要加lock啊
db其实是sqlhelper之类的东西,这就是insert函数而已。没有删除操作。 我试试lock吧。
threenewbee 2014-10-11
  • 打赏
  • 举报
回复
如果上一个timer没有执行完,又到了时间点,那么会再开一个线程,所以可能timer线程不止一个,你需要同步所有的公有变量。
於黾 2014-10-11
  • 打赏
  • 举报
回复
右键,查找所有引用,看到底其他地方使用使用了这个集合 此外,db.add也是有可能会出问题的 db这个对象,两个线程在用,一个往里add,另一个循环取出来remove 这个要加lock啊

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧