BackgroundWorker类
async/await特性适合那些需要在后台完成的不相关的小任务,有时候,需要另建一个线程,在后台持续运行以完成某项工作,并不时地与主线程进行通信,BackgroundWorker类就是为此而生。
BackgroundWorker类的主要成员
- 属性
- WorkerReportsProgress 设置后台任务是否可以把它的进度汇报给主线程
- WorkerSupportsCancellation 是否支持从主线程取消
- IsBusy 检查后台任务是否正在运行
- CancelationPending 状态值,布尔类型
- 方法
- RunWorkerAsync() 获取后台线程并执行DoWork事件处理程序
- CancelAsync() 把CancellationPending属性设置为true。DoWork事件处理程序需要检查这个属性来决定是否应该停止处理
- ReportProgress() DoWork工作的时候向主线程汇报进度
- 事件
- DoWork 在后台线程开始的时候触发
- ProgressChanged 在后台任务汇报状态的时候触发
- RunWorkerCompleted 在后台工作线程退出的时候触发
使用示例:
using System.Threading;
using System.Windows;
using System.ComponentModel;
namespace WpfForAsync
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
// 首先需要创建BackgroundWorker对象
BackgroundWorker bgWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
// 设置BackgroundWorker属性
// WorkerReportsProgress设置工作线程为主线程汇报进度
bgWorker.WorkerReportsProgress = true;
// 设置支持从主线程取消工作线程
bgWorker.WorkerSupportsCancellation = true;
// 连接BackgroundWorkder对象的处理程序
//DoWork是必须的
bgWorker.DoWork += BgWorker_DoWork;
//ProgressChanged与RunWorkerCompleted这两个是可选的
bgWorker.ProgressChanged += BgWorker_ProgressChanged;
bgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
}
private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
progressBar.Value = 0;
if (e.Cancelled)
{
MessageBox.Show("Process was cancelled.", "Process Cancelled");
}
else
{
MessageBox.Show("Process completed normally.", "Process Completed");
}
}
private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
}
/// <summary>
/// 这里是希望在后台工作的代码
/// 它是在独立的线程中执行的
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i <= 10; i++)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
else
{
/// 后台线程通过调用ReportProgress方法与主线程通信。
/// 届时将触发ProgressChanged事件
/// 主线程可以处理附加到ProgressChanged事件上的处理程序
worker.ReportProgress(i * 10);
Thread.Sleep(500);
}
}
}
private void btnProcess_Click(object sender, RoutedEventArgs e)
{
if (!bgWorker.IsBusy)
{
//主线程调用RunWorkerAsync的时候,会触发DoWork事件
bgWorker.RunWorkerAsync();
}
}
private void progressBar_Click(object sender, RoutedEventArgs e)
{
// 通知后台线程退出
// 此时会将后台线程类的CancellationPending属性设置为true
// DoWork事件处理程序会定期检查CancellationPending确定是否要退出
// 如果后台线程退出,则会触发RunWorkerCompleted事件
bgWorker.CancelAsync();
}
}
}
这是一个WPF程序,前端代码与上一节的一样,后端代码使