我的一个小工具软件开发(5)—U盘小秘

阅读次数: 1,893

  • A+
所属分类:C#

 

为了搞定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:


往期回顾:

  1. 我的一个小工具软件开发(1)—U盘小秘
  2. 我的一个小工具软件开发(2)—U盘小秘
  3. 我的一个小工具软件开发(3)—U盘小秘
  4. 我的一个小工具软件开发(4)—U盘小秘
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信公众号扫一扫
  • weinxin
ChemistrySir

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: