这个系列的文章,主要是平时做C#.NET(Framework 3.5)开发的时候,积累的经验和技巧。我们平时总有这样的体会,遇到一个特别难解决的问题,网上寻它千百度也没能搜索到有用的信息。这时你肯定会想,解决了这个问题一定要记下来。实际上待你埋头苦干终于搞定它的时候,往往被喜悦和成就感充斥,再加上这个问题本身解决的方法可能简单无比,于是忘记去记录下来。本篇就从零开始,回顾五年编程经验积累的各种奇葩问题的解决方法。

DataGridView是个神奇的控件,与数据集绑定显示,方便、耐用。但是这样一个封装了99%内部实现的控件,必然会出现你让你抓狂的异常。

来看今天遇到的问题:主窗口有一个DataGridView控件,它的DataSource是atable;在线程中获取一行数据arow,添加到atable中,然后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了吧。从我们开发者自身角度来讲,保持一个良好的编程习惯至关重要——线程不访问其他线程的变量,必须访问的时候所有操作都用委托。如果上述例子的开发者能遵循这个原则,就不会遇到这个难题。

最新文章

  1. Koala-Sass编译
  2. 为什么你还在用嵌入式的方式来使用mod_wsgi?
  3. Asp.net Core WebApi 支持json/xml格式的数据返回
  4. Html - Bootstrap Panel面板
  5. 第十二届浙江省大学生程序设计大赛-Capture the Flag 分类: 比赛 2015-06-26 14:35 10人阅读 评论(0) 收藏
  6. eclipse中logcat偶尔不显示log的问题解决办法
  7. cocos2d-js屏幕任何位置点击开始的实现
  8. asp.net正则表达式过滤标签和数据提取
  9. wpf 只在window是ShowDialog打开时才设置DialogResult
  10. erlang mnesia数据库简单应用
  11. Js中Array数组学习总结
  12. socketpair创建双向通信的管道(全双工通信)
  13. 推荐几本FPGA书籍(更新中)
  14. php实现聊天室功能
  15. 3-idiots hdu4609 母函数+FFT 组合数学题
  16. mysqldump备份时保持数据一致性
  17. 同一个IIS绑定多个Htts 站点问题
  18. php使用json_encode后出现中文乱码的解决方法
  19. linux根文件系统 /etc/resolv.conf 文件详解(转)
  20. Moment.js的一些用法

热门文章

  1. python之SocketServer编程
  2. Linux学习系列之lvs+keepalived
  3. 自己构建的Lumbda表达式
  4. windows 7 忘記密碼,用“带命令行的安全模式”
  5. JAVA获取操作系统的信息
  6. VB.NET+三层 机房收费系统之组合查询
  7. SQLite数据库基本操作
  8. 关于使用Xshell远程连接启动tomcat导致图片不显示,报错Could not initialize class sun.awt.X11GraphicsEnvironment解决方案
  9. Qt Quick之StackView具体解释(2)
  10. HDU5294 Tricks Device(最大流+SPFA) 2015 Multi-University Training Contest 1