浅谈.NET下的多线程和并行计算(八)Winform中多线程编程基础 上
首先我们创建一个Winform的应用程序,在上面添加一个多行文本框和一个按钮控件,按钮的事件如下 :
首先我们可以把这个操作理解为一个非常耗时的操作,它至少占用1秒的时间。在1秒后,我们整了一 个大字符串作为文本框的值,然后在标签上显示给文本框赋值这个UI渲染行为需要的时间,程序执行结果 如下: 我们可以感受到,在点击了按钮之后整个程序的UI就卡住了,没有办法拖动没有办法改变大小,用于 体验非常差。一般能想到会新建一个线程来包装这个方法,使得UI线程不被卡住:
使用调试方式运行程序的话会得到如下的异常(非调试方式不会): 虽然我们知道这样设置: Control.CheckForIllegalCrossThreadCalls = false; 可以屏蔽这个错误,但是在非创建控件的线程去更新控件的状态的做法会导致很多问题,比如死锁和 控件部分被更新等。微软推荐我们使用Control的Invoke或BeginInvoke方法来把涉及到控件状态更新的操 作让UI线程去做:
你可能会想到这么写,但是运行程序后可以发现界面依然是卡死。想一下,虽然我们新开了一个线程 ,但是马上又把整个代码段交给UI线程去做了,当然起不到效果。其实这个方法的工作可以分为两部分, 一部分是我们数据的计算,一部分是把计算好的数据显示在界面上,我们只应该把真正和UI相关的操作放 到 Invoke中让UI线程去做:
再测试一次可以发现,UI在前1秒多的时间没有卡死,在最后的一点时间还是卡死了。在继续研究卡死 问题之前我们来看一下,Control提供了InvokeRequired属性来让我们判断当前线程是不是UI线程,或者 说当前的操作是否需要进行Invoke:
通过非调试方式启动程序可以得到如下结果: 很明显: 1) 在线程外的赋值不需要Invoke(在UI线程) 2) 在线程内的赋值需要Invoke(不在UI线程) 3) 在Invoke中的赋值已经封送给UI线程,所以不需要Invoke 继续研究卡死问题,您可能会想到,Control还提供了一个BeginInvoke方法,我们来试试看:
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |