一、概述
BackgroundWorker是一个基于事件的异步模式(EAP)的实现方式,用于管理工作线程。
BackgroundWoker使用线程池,所以绝不允许调用Abort,否则会导致线程池异常。
二、创建及运行
使用步骤:
- 创建BackgroundWorker对象,注册Dowork事件。
- 调用对象的RunWokerAsync方法执行异步操作,可以选用Object参数。
class Program
{
static BackgroundWorker _bw = new BackgroundWorker();
static void Main()
{
_bw.DoWork += bw_DoWork;
_bw.RunWorkerAsync ("Message to worker");
Console.ReadLine();
}
static void bw_DoWork (object sender, DoWorkEventArgs e)
{
// 这里在工作线程上执行
Console.WriteLine (e.Argument); // 打印 "Message to worker"
// 执行耗时的任务...
}
}
三、其他功能
(一)RunWokerCompleted 完成事件
Backgroundworker在DoWork事件结束后会触发RunWorkerCompleted事件。
RunWorkerCompleted事件不是必须的,但是可以查询在Dowork中发生的异常。
RunWorkerCompleted事件中可以直接更新UI控件,不需要通过封送。
(二)ProgressChanged 进度事件
- 设置Backgroundworker对象的WorkerReportsProgress属性为True。
- 在Dowork事件中周期性的调用ReportProgress方法触发ProgressChanged事件,报告进度百分比的值。
- 注册ProgressChanged事件,查询ProgressPercentage属性。
- ProgressChanged事件中可以直接更新UI控件,一般用该事件更新进度条控件。
(三) 取消功能
- 设置WorkerSupportsCancellation属性为True。
- 在Dowork事件中周期性的检查CancellationPending属性,如果为true,就设置事件参数的Cancel属性为true,然后返回。(也可以直接设置Cancel来退出)
- 调用CanelAsync来请求取消。
代码:
using System;
using System.Threading;
using System.ComponentModel;
class Program
{
static BackgroundWorker _bw;
static void Main()
{
_bw = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bw.DoWork += bw_DoWork;
_bw.ProgressChanged += bw_ProgressChanged;
_bw.RunWorkerCompleted += bw_RunWorkerCompleted;
_bw.RunWorkerAsync ("Hello to worker");
Console.WriteLine ("Press Enter in the next 5 seconds to cancel");
Console.ReadLine();
if (_bw.IsBusy) _bw.CancelAsync();
Console.ReadLine();
}
static void bw_DoWork (object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i += 20)
{
if (_bw.CancellationPending) { e.Cancel = true; return; }
_bw.ReportProgress (i);
Thread.Sleep (1000); // 仅仅为了演示...
} // 真实环境中不要在线程池线程上使用 Sleep !
e.Result = 123; // 这会传递给 RunWorkerCompleted
}
static void bw_RunWorkerCompleted (object sender,
RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
Console.WriteLine ("You canceled!");
else if (e.Error != null)
Console.WriteLine ("Worker exception: " + e.Error.ToString());
else
Console.WriteLine ("Complete: " + e.Result); // 来自 DoWork
}
static void bw_ProgressChanged (object sender,
ProgressChangedEventArgs e)
{
Console.WriteLine ("Reached " + e.ProgressPercentage + "%");
}
}
输出结果:
Press Enter in the next 5 seconds to cancel
Reached 0%
Reached 20%
Reached 40%
Reached 60%
Reached 80%
Reached 100%
Complete: 123
Press Enter in the next 5 seconds to cancel
Reached 0%
Reached 20%
Reached 40%
You canceled!