- A+
为了搞定listview不能同步更新的问题,经过多方查找,知道了是线程问题。
[h2title]关于线程,自己的一点理解[/h2title]
cpu在执行程序时,总是按照你提前规划好的步骤一步一步执行下去,当整个程序只有一个线程时,而整个程序需要执行的任务又较多且其中某些步骤比较耗时的时候,整个程序由于忙于耗时的工作,导致此时不能响应用户的任何操作,比如:拖动程序界面、鼠标的点击。程序此时同样不能响应窗口内其他部件的事件响应,导致不能同步显示listview窗口。只能等到程序把耗时的工作做完了,原来堆积的事件才能得以进行,表现为:假死一段时间后,listview突然出现大量的数据。
使用多线程,就能很好的解决这个问题。如果原来cpu给程序开了一个跑道,不管你跑得快、跑得慢,如果跑得慢的占有跑道,后面跑的更快就不能超车,只能在后面跟着。多线程,就是让cpu开辟两个跑道,此时,就能够让跑得慢的独自占有一个跑道,这样,就解决了不同的任务同时响应的问题。
[h2title]关于委托,自己的学习[/h2title]
可是,有出现了新的问题。文件的新旧比对工作非常耗时,我想把它放到子线程中,在子线程中,通过比对文件,最后更新文件,都是在子线程中进行的,完成后需要更新在主线程中listview,此时,有出现新的问题:在子线程内想修改主线程的控件值时,是会直接抛出系统异常的,所以需要通过委托来实现。
在Windows应用程序中,绘制窗体和控件是由“UI线程”负责的,因此,Windows不允许其它线程直接访问可视化控件。其原因是Windows无法控制其它线程将如何使用这些控件,而对控件某些属性的设置和方法调用有可能直接影响到控件的外观。这样想想就明白了:如果UI线程正在绘制按钮的同时,另一个线程要修改按钮上的文字,第三个线程也要尝试着修改此按钮的文字,这个按钮最终的样子,就是一个不确定的状态!
因此,在.NET中有这样一个基本编程原则:
[danger]不能跨线程直接访问窗体和控件,对它们的访问必须转由UI线程来负责处理。[/danger]
在.NET Framework中,所有可视化的控件(包括窗体)都是从System.Windows.Forms.Control类派生出来的,考虑到跨线程访问控件的需要,Control类提供了相应的方法完成跨线程更新界面工作。
Control.Invoke方法定义如下:
public object Invoke(Delegate method);
经过日夜兼程的学习,总结学习成果,跨线程访问控件步骤可以总结一下:
[success]
1、将访问的控件代码封装为一个方法。我主要想在线程中修改UI线程的listview控件,那么,就封装listview控件。
2、根据方法自定义一个对应委托。看需要是否传递参数,定义方法略有不同。
3、增加一个定义的委托类型的字段,并把前面访问控件的方法"挂接"到此字段中;
4、编写一个线程方法,在此方法中调用要访问控件的Invoke方法,并把定义好了的委托字段做为参数传入.
5、在合适的地方创建线程并启动运行。
[/success]
接下来的工作,非常顺利,做了少许改写,即可实现线程间的调用工作,软件基本实现功能,各功能测试,已经正常显示。
通过今天的编写程序,感觉自己学到了更多的知识,委托、线程调用已经懂得怎么回事了。收获颇丰! :confused:
往期回顾:
- 我的微信
- 微信扫一扫
-
- 我的微信公众号
- 微信公众号扫一扫
-