本节书摘来自华章出版社《C#多线程编程实战(原书第2版)》一书中的第3章,第3.8节,作者(美)易格恩·阿格佛温(Eugene Agafonov),黄博文 黄辉兰 译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.8 使用BackgroundWorker组件
本节实例演示了另一种异步编程的方式,即使用BackgroundWorker组件。借助于该对象,可以将异步代码组织为一系列事件及事件处理器。你将学会如何使用该组件进行异步编程。
3.8.1 准备工作
为了学习本节,你需要安装Visual Studio 2015。除此之外无需其他准备。本节的源代码放置在BookSamplesChapter3Recipe7目录中。
3.8.2 实现方式
请执行以下步骤来学习如何使用BackgroundWorker组件:
1.启动Visual Studio 2015。新建一个C#控制台应用程序项目。
2.在Program.cs文件中加入以下using指令:
3.在Main方法下面加入以下代码片段:
4.在Main方法中加入以下代码片段:
5.运行程序。
3.8.3 工作原理
当程序启动时,创建了一个BackgroundWorker组件的实例。显式地指出该后台工作者线程支持取消操作及该操作进度的通知。
接下来是最有意思的部分。我们没有使用线程池和委托,而是使用了另一个C#语法,称为事件。事件表示了一些通知的源或当通知到达时会有所响应的一系列订阅者。在本例中,我们将订阅三个事件,当这些事件发生时,将调用相应的事件处理器。当事件通知其订阅者时,具有特殊的定义签名的方法将被调用。
因此,除了将异步API组织为Begin/End方法对,还可以只启动一个异步操作然后订阅给不同的事件。这些事件在该操作执行时会被触发。这种方式被称为基于事件的异步模式(Event-based Asynchronous Pattern,简称EAP)。这是历史上第二种用来构造异步程序的方式,现在更推荐使用TPL,第4章中将会描述该方式。
我们共定义了三个事件。第一个是DoWork事件。当一个后台工作对象通过RunWorker-Async方法启动一个异步操作时,该事件处理器将被调用。该事件处理器将会运行在线程池中。如果需要取消操作,则这里是主要的操作点。同时也可以提供该操作的运行进程信息。最后,得到结果后,将结果设置给事件参数,然后RunWorkerCompleted事件处理器将被调用。在该方法中,可以知道操作是成功完成,还是发生错误,抑或被取消。
基于此,BackgroundWorker组件实际上被使用于Windows窗体应用程序(Windows Forms Applications,简称WPF)中。该实现通过后台工作事件处理器的代码可以直接与UI控制器交互。与线程池中的线程与UI控制器交互的方式相比较,使用BackgroundWorker组件的方式更加自然和好用。