更新DataGridView数据源导致WinForm主程序无响应
来源:互联网 发布:知乎答案加载不出来 编辑:程序博客网 时间:2024/05/22 04:30
原文地址:http://www.cnblogs.com/gudansong/p/3144189.html
问题:主窗口有一个DataGridView控件,它的DataSource是一个DataTable;在工作线程中添加一个新行到DataTable数据源中,然后invoke主线程去修改MainForm上一个Label的Text。线程函数代码如下:
threadfun(){//......atable.AddRow(arow);Invoke(adelegate);//......}
测试exe程序的时候出现主界面无响应的情况,反复重启发现每当添加第N条数据后问题出现,N是某个定值。使用VS调试源代码,问题消失。
做C#开发最难受的情况就是,VS调试一切OK,运行exe出错。这种情况我们以后会经常遇到,可以理解为.Net Framework的运行时和调试时是略有不同的,不再深入追究。使用VS附加进程调试,找到源头是invoke的委托代码执行被挂起,导致主界面无响应。
解决方法:在线程中,对DataGridView的数据源进行的操作都使用委托。
分析:数据表atable是DataGridView的数据源,DataGridView是主线程的控件,虽然在线程函数里可以访问同一命名空间下的引用,但是一旦牵扯到控件,最好还是让主线程去操作,否则就会出现各种意想不到的问题,比如今天遇到的。
刨根问底:向atable添加一行arow,这会导致DataGridView重绘,因为绑定的数据源自动显示。从这个角度来看,今天的例子犯了一个常见的错误:从线程修改主线程控件。特殊的地方是这个重绘操作是.Net内部通过某种机制实现的,它并不违反约束,前N-1次操作并没有异常发生就能看出来。那么,为什么第N次添加操作就一定会触发这个问题呢?
真相:通过观察视图设计,我发现第N条数据会使DataGridView自动添加纵向滚动条,为了验证这是否是真相,我减小了DataGridView的高度,果然小于第N条数据就出现了问题,从而确定就是这个添加滚动条的动作导致主线程挂起,窗口无响应。
总结:想弄明白这个问题的最终答案,必须完全理解DataGridView的内部实现机制,这个机制允许从线程向DataGridView添加行并显示,但是当自动创建滚动条的时候会挂起,我想这也算是一个bug了吧。从我们开发者自身角度来讲,保持一个良好的编程习惯至关重要——线程不访问其他线程的变量,必须访问的时候所有操作都用委托。如果上述例子的开发者能遵循这个原则,就不会遇到这个难题。
- 更新DataGridView数据源导致WinForm主程序无响应
- OpenFileDialog.ShowDialog()导致WinForm无响应解法
- DataGridView更新数据源
- c# winform 添加dataGridView数据源
- C#winform dataGridView更新数据库
- C#winform dataGridView更新数据库
- WinForm 2.0 无代码DataGridView绑定
- c#中多线程写DataGridView出现滚动条导致程序卡死(无响应)的解决办法
- ireport加载JavaBean无响应,创建JavaBean数据源无响应。
- winform datagridview实时更新显示查询结果
- WinForm程序用使用List对象绑定DataGridView数据源
- winform中datagridview新增combobox列绑定数据源
- C# Winform datagridview控件绑定数据源后列顺序混乱
- .net的Winform中,dataGridView数据源动态绑定!
- WinForm程序用使用List对象绑定DataGridView数据源
- WinForm程序用使用List对象绑定DataGridView数据源
- 版本Ui更新响应和无响应
- ctrl+s导致SecureCRT,SSH无响应!
- 使用Windows Live Writer写BLOG
- FAT,FAT32,NTFS单目录文件数量限制
- [C++]LeetCode: 57 Excel Sheet Column Title
- TFS错误-TF249053
- spring定时任务
- 更新DataGridView数据源导致WinForm主程序无响应
- 为什么毕业后五年,你们的贫富差距越拉越大
- 十进制转换为N进制问题
- 关于CLOSE BY CLIENT STACK TRACE
- 自动布局框架介绍
- NGUI系列教程五(角色信息跟随)
- 掀开C#的一层面纱
- 多线程 -- 等待函数、事件内核对象
- 二叉树的层次遍历