下面的伪代码是程序的大概,错误原因是因为线程b修改数据源时正巧碰到用户操作控件引发的,系统实际有多个线程操作这个datagridview和数据源。
线程a
{
DataViewdv = new DataView(db);
dv.RowFilter = "delete = false"
this.datagridview.DataSource= dv;
}线程b(5秒执行一次)
{
foreach(var r in db.rows)
{
if(r["tm"] < DateTime.Now) r["delete"] = true; }
}
当我正在操作datagridview的时候,比如对这个datagridview进行双击、拖动滚动条、编辑单元格文本,这时正好遇到了线程b执行,突然datagridview数据源有所减少或者全部消失,这时崩溃,错误定位到Main()方法中,错误提示是“在 System.NullReferenceException 中第一次偶然出现的“System.Windows.Forms.dll”类型的异常”,用try也不能捕获异常,跟找不到确切的文字。请问如何解决多线程操作datagridview会出现系统崩溃的问题?
线程a
{
DataViewdv = new DataView(db);
dv.RowFilter = "delete = false"
this.datagridview.DataSource= dv;
}线程b(5秒执行一次)
{
foreach(var r in db.rows)
{
if(r["tm"] < DateTime.Now) r["delete"] = true; }
}
当我正在操作datagridview的时候,比如对这个datagridview进行双击、拖动滚动条、编辑单元格文本,这时正好遇到了线程b执行,突然datagridview数据源有所减少或者全部消失,这时崩溃,错误定位到Main()方法中,错误提示是“在 System.NullReferenceException 中第一次偶然出现的“System.Windows.Forms.dll”类型的异常”,用try也不能捕获异常,跟找不到确切的文字。请问如何解决多线程操作datagridview会出现系统崩溃的问题?
解决方案 »
- 纠结了两天的DataContractSerializer 反序列化xml的问题,在线等啊
- Session过期问题
- 引用水晶报表dll文件
- C#中页面加载时的焦点问题
- 写开机自动运行程序 用写服务,和写注册表 两种方法 各有什么利弊呢?
- 使用SendMessage获取文本失败!麻烦大家帮我看一下
- winform C#怎么让checkedlistbox最多只能选中3项
- 数组作为属性时值是怎么传递的呢
- 千元大奖寻求Windows Messenger及MSN Messenger在.NET下的编程解决方案
- 前进,后退,上移,下移,又该如何???左DataGrid中……
- RDLC报 值不在预期的范围内 错误.
- C#操作Excel刷新数据出现的问题,几个月了呀,高手咋还没出现
//线程a
{
lock()
{
DataViewdv = new DataView(db);
dv.RowFilter = "delete = false"
this.datagridview.DataSource= dv;
}
}//线程b(5秒执行一次)
{
lock()
{
foreach(var r in db.rows)
{
if(r["tm"] < DateTime.Now) r["delete"] = true;
}
}
http://www.cnblogs.com/chenxizhang/archive/2008/09/09/1287421.html
是的,如果楼主对这方面不太熟悉的话,建议你使用线程池,比如backgroundworker什么的,可以省去很多麻烦
现在发现.NET版的,有答案也很久不结贴的。RP啊。
请问这里的lock()不锁任何对象吗?
现在的主要问题是,即使是加入了锁,但当线程b运行修改数据源的同时,datagridview上显示的数据条数也有变化,如果这个时候正在对datagridview进行操作,就会引起系统崩溃。
如何禁止这些操作?在线程b运行前后我加入了 datagridview.enabled=false,虽然可以减少崩溃的次数,但还不能彻底解决问题。
试试在b线程 Monitor.Enter(dv)看看 不过记得在trycatch里释放 否则可能死锁
帮lz顶
this.datagridview.DataSource= dv;
这句就在访问了把
DataViewdv = new DataView(db);
dv.RowFilter = "delete = false"
this.datagridview.DataSource= dv
做成一个委托方法
{
DataView dv = new DataView(db);
dv.RowFilter = "delete = false";
this.datagridview.DataSource = dv;
} void Thread_a()
{
SetDataSouce PDoSetDataSouce = new SetDataSouce(DoSetDataSouce);
PDoSetDataSouce();
} void Thread_b()
{
// ...
}
delegate void SetDataSouce(); void DoSetDataSouce()
{
DataView dv = new DataView(/*db*/);
dv.RowFilter = "delete = false";
this.datagridview.DataSource = dv;
} void Thread_a()
{
SetDataSouce PDoSetDataSouce = new SetDataSouce(DoSetDataSouce);
if (datagridview.InvokeRequired)
datagridview.Invoke(PDoSetDataSouce, null);
else
DoSetDataSouce();
} void Thread_b()
{
// ...
}