C#中的BackgroundWorker控件

时间:2021-10-05 05:08:45

BackgroundWorker是.NET Framework 里用来执行多线程任务的控件,它允许开发人员在一个单独的线程上执行一些操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 始终处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。 可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。 如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。 

语法

public class BackgroundWorker : Component

 

构造函数

  名称 说明
BackgroundWorker 初始化 BackgroundWorker 类的新实例。

属性

  名称 说明
CancellationPending 获取一个值,指示应用程序是否已请求取消后台操作。
CanRaiseEvents 获取一个指示组件是否可以引发事件的值。 (继承自 Component。)
Container 获取 IContainer,它包含 Component (继承自 Component。)
DesignMode 获取一个值,用以指示 Component 当前是否处于设计模式。 (继承自 Component。)
Events 获取附加到此 Component 的事件处理程序的列表。 (继承自 Component。)
IsBusy 获取一个值,指示 BackgroundWorker 是否正在运行异步操作。
Site 获取或设置 Component 的 ISite (继承自 Component。)
WorkerReportsProgress 获取或设置一个值,该值指示 BackgroundWorker 能否报告进度更新。
WorkerSupportsCancellation 获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。

 方法

  名称 说明
CancelAsync 请求取消挂起的后台操作。
CreateObjRef 创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。 (继承自MarshalByRefObject。)
Dispose() 释放由 Component 使用的所有资源。 (继承自 Component。)
Dispose(Boolean) 释放 Component 占用的非托管资源,也可以选择释放托管资源。 (继承自 Component。)
Equals(Object) 确定指定的 Object 是否等于当前的 Object (继承自 Object。)
Finalize 在通过垃圾回收将 Component 回收之前,释放非托管资源并执行其他清理操作。 (继承自 Component。)
GetHashCode 用作特定类型的哈希函数。 (继承自 Object。)
GetLifetimeService 检索控制此实例的生存期策略的当前生存期服务对象。 (继承自 MarshalByRefObject。)
GetService 返回一个对象,该对象表示由 Component 或它的 Container 提供的服务。 (继承自 Component。)
GetType 获取当前实例的 Type (继承自 Object。)
InitializeLifetimeService 获取控制此实例的生存期策略的生存期服务对象。 (继承自 MarshalByRefObject。)
MemberwiseClone() 创建当前 Object 的浅表副本。 (继承自 Object。)
MemberwiseClone(Boolean) 创建当前 MarshalByRefObject 对象的浅表副本。 (继承自 MarshalByRefObject。)
OnDoWork 引发 DoWork 事件。
OnProgressChanged 引发 ProgressChanged 事件。
OnRunWorkerCompleted 引发 RunWorkerCompleted 事件。
ReportProgress(Int32) 引发 ProgressChanged 事件。
ReportProgress(Int32, Object) 引发 ProgressChanged 事件。
RunWorkerAsync() 开始执行后台操作。
RunWorkerAsync(Object) 开始执行后台操作。
ToString 返回包含 Component 的名称的 String(如果有)。 不应重写此方法。 (继承自 Component。)

事件

  名称 说明
Disposed 当通过调用 Dispose 方法释放组件时发生。 (继承自 Component。)
DoWork 调用 RunWorkerAsync 时发生。
ProgressChanged 调用 ReportProgress 时发生。
RunWorkerCompleted 当后台操作已完成、被取消或引发异常时发生。

    
示例

本代码运行环境:Windows XP, Visual Studio 2010, .NET Framework 4, C#

下面的代码示例演示 BackgroundWorker 类异步执行耗时的基本知识。 下图显示输出的示例。

C#中的BackgroundWorker控件

要尝试该代码,可创建 Windows 窗体应用程序。 添加一个名为 resultLabel 的 Label 控件并添加两个名为 startAsyncButton 和 cancelAsyncButton 的 Button 控件。 创建这两个按钮的 Click 事件处理程序。 从工具箱中的“组件”选项卡中,添加命名为 backgroundWorker1 的 BackgroundWorker 组件。 创建 DoWork、 ProgressChanged 和 BackgroundWorker 的 RunWorkerCompleted 事件处理程序。

在窗体的代码中,用下列代码替换现有代码。


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication5
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
}

private void startAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
// 启动异步操作
backgroundWorker1.RunWorkerAsync();
}
this.startAsyncButton.Enabled = false;
}

private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
// 取消异步操作
backgroundWorker1.CancelAsync();
}
this.startAsyncButton.Enabled = true;
}

//主任务的实现
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;

for (int i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// 执行计时操作并且报告进度
System.Threading.Thread.Sleep(500);
worker.ReportProgress(i * 10);
}
}
}

//更新进度
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
resultLabel.Text = (e.ProgressPercentage.ToString() + "%");
}

//处理后台操作结果
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}
}
}