Backgroundworker类学习
Backgroundworker 类
BackgroundWorker 是微软添加的一个组件,主要对线程的访问提供了一种安全的方式。简单的说就是对 Thread 的一次封装。
该类主要适用于关于进度条之类的UI更新,可以考虑使用该类型
常用属性
| 属性 | 作用 |
|---|---|
| WorkerReportsProgress | 是否可以报告进度。 |
| WorkerSupportsCancellation | 是否允许异步中止 |
| IsBusy | 是否在运行 |
| CancellationPending | 判断 BackgroundWorker 是否已经异步取消 |
常用方法
| 方法 | 作用 |
|---|---|
| RunWorkerAsync | 开始执行任务。并触发 DoWork 事件 |
| ReportProgress | 异步提醒,触发 ProgressChanged 事件,使用该方法时,必须设置 WorkerReportsProgress 为 True |
| CancelAsync | 取消 BackgroundWorker 操作,使用该方法时,必须设置 WorkerSupportsCancellation 为 True |
| Dispose | 释放该实例产生的资源 |
事件
| 事件 | 作用 |
|---|---|
| DoWork | 执行 RunWorkerAsync 后触发,异步执行的认为。 |
| ProgressChanged | 执行 ReportProgress 时触发,异步获得进度。 |
| RunWorkerCompleted | 线程结束时触发,当 DoWork 事件运行结束时触发,发生异常或者取消时也会发生。 |
基本使用(开启和关闭 BackgroundWorker)
private BackgroundWorker worker = new BackgroundWorker();
private int i = 0;
public MainWindow()
{
InitializeComponent();
worker.WorkerSupportsCancellation = true;
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
}
//开始时触发
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
Dispatcher.Invoke(() =>
{
textblock.Text = i++.ToString();
});
Thread.Sleep(1000);
}
}
//结束时触发
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
textblock.Text = "完成";
}
//开始
private void Button_Click(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync();
}
//停止
private void Button_Click_1(object sender, RoutedEventArgs e)
{
worker.CancelAsync();
}
RunWorkerAsync() 方法可以传递参数,参数类型是 object 类型,修改上面的代码
传递的参数通过 DoWork 事件中的第二个参数中的 Argument 属性获取,该属性是 object 类型
private void Button_Click(object sender, RoutedEventArgs e)
{
worker.RunWorkerAsync("你好");
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
MessageBox.Show(e.Argument?.ToString());
}
注意要使用 CancelAsync 方法取消线程时,要设置 WorkerSupportsCancellation 属性为 true
DoWorkEventArgs 中的参数
- Argument:当调用 RunWorkerAsync 方法并传递参数时,可通过该属性获取 RunWorkerAsync 方法传递的参数
- Result:object 类型,可以设置该属性的值,当 DoWork 事件结束时,会触发 RunWorkerCompleted 事件,通过 RunWorkerCompleted 事件的 RunWorkerCompletedEventArgs 参数中的 Result 属性获取
修改上面的代码
//开始时触发
private void Worker_DoWork(object? sender, DoWorkEventArgs e)
{
e.Result = 10;
}
//结束时触发
private void Worker_RunWorkerCompleted(object? sender, RunWorkerCompletedEventArgs e)
{
//输出:结果:10
textblock.Text = $"结果:{e.Result}";
}
更新UI
wpf 中要更新 UI 需要在主线程执行,不能在其他线程中执行,一般使用 dispatcher 属性,而 Backgroundworker 类中提供了事件可以用来更新 UI
ProgressChanged 事件,该事件使用时需要设置 WorkerReportsProgress 属性为 true ,当调用 ReportProgress 方法时才会触发,该事件中的代码是在主线程(UI 线程)上执行的,修改上面的代码
public MainWindow()
{
InitializeComponent();
worker.WorkerSupportsCancellation = true;
worker.WorkerReportsProgress = true;//允许报告进度
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
worker.ProgressChanged += Worker_ProgressChanged;
}
//开始时触发
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
if (worker.CancellationPending)
{
e.Cancel = true;
break;
}
i++;
worker.ReportProgress(i);
Thread.Sleep(1000);
}
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
textblock.Text = e.ProgressPercentage.ToString();
}
ReportProgress 方法可以传递两个参数,第一是 int 类型,第二个参数是 object 类型
- 第一个参数的值通过
ProgressChanged事件中的第二个参数中的 ProgressPercentage 属性获取,该属性是 int 类型 - 第二个参数的值通过
ProgressChanged事件中的第二个参数中的 UserState 属性获取,该属性是 object 类型

浙公网安备 33010602011771号