C#中跨线程操作控件2011-07-16 博客园 kingsky一、前面的话对于一些耗时型操作(如文件下载),让主线程去处理不是明智的选择,虽然这样做会使得程序开发起来很简单。因为WinForm程序设计的 准则之一就是Responsive,即让用户觉得程序一直在工作,而不是感觉它在罢工(呵呵,事实上,程序不会罢工,只是你没给他表现得机会, 如果它有情感,会觉得委屈死)。.Net FrameWork支持在程序用应用线程编程,这可以很好的解决上述问题,不过有时候直接使用Thread和 Threadstart显得有些繁琐也没必要,为此.Net Framework提供了BackgroundWorker组件来应付一些简单的应用环境。本文将分别对上述两种情况的跨线程操作控件方法进行阐述。二、BackgroundWorker下的跨线程操作控件BackgroundWorker是个很好的伙计,因为它可以忙你搞定许多脏活累活。具体的讲,它可以自动的帮你创建工作线程,可以在工作时把工作 的进展情况告诉给你,可以在工作完成时通知并帮你做一些收尾的工作,当你觉得他很烦的时候,你还可以随时让他停下来。BackgroundWorker组件提供了三个事件:DoWork,ProgressChanged和RunWorkerCompleted。Dowork顾名思义是用来处理工作业务的 ,在这里面加入你想让工作线程在后台处理的代码即可。但是在这个事件中不能加入跨线程操作的代码。如下图,当我试图改变Label.Text的 值时,抛出了异常信息:

不过这里有个例外,就是对于ToolStrip及其从该类继承过来的容器控件,某些在该容器上的控件(如StatusLabel)可以在工作线程 中直接操作。至于为啥,我没有去深究,不过根据图中的提示信息,一个很合理的解释就是这类控件和BackgroundWorker由同一个线程创建。ProgressChanged和RunWorkerCompleted事件分别用来报告工作线程的工作情况和在工作线程结束后进行一些操作。这两个事件都支 持跨线程操作控件。下面通过一个简单的实例进行验证。用程序实现将一个目录中的文件拷贝至另外一个目录。1.程序界面设计如下:

2.工作流程:(1)设置源目录和目标目录(2)拷贝文件,在ListView中显示拷贝信息,更新状态栏中的进度条和当前处理文件信息(3) 拷贝过程结束后,用MessageBox提示拷贝文件数量,同时清空源目录和目标目录信息。