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 类型
posted @ 2023-10-08 16:27  青蛙001  阅读(55)  评论(0)    收藏  举报