C# BackgroundWorker控件

1.BackgroundWorker控件

BackgroundWorker在后台持续运行以完成某项工作,并不时地与主线程进行通信
BackgroundWorker常用的有4个属性、3个方法、3个事件:
4个属性:

(1)WorkerReportsProgress:设置后台任务是否可以把它的进度汇报给主线程
(2)WorkerSupportsCancellation:是否支持从主线程取消
(3)IsBusy:检查后台任务是否正在运行
(4)CancellationPending:获取一个值,指示应用程序是否已请求取消后台操作。如果应用程序已请求取消后台操作,则为 true;否则为 false。 默认值为 false

3个方法:

RunWorkerAsync():调用RunWorkrAsync方法获取后台线程并且执行DoWork事件处理程序;
CancelAsync():调用CancelAsync方法把CancellationPending属性设置为true。DoWork事件处理程序需要检查这个属性来决定是否应该停止处理;
ReportProgress();DoWork事件处理程序在希望向主线程汇报进度的时候,调用ReportProcess方法;调用这个方法后,将触发ProgressChanged事件,主线程可以处理附加到ProgressChanged事件上的处理程序。

3个事件:

DoWork:在后台线程开始的时候触发DoWork
ProgressChanged:在后台任务汇报状态的时候触发ProgressChanged事件
RunWorkerCompleted:后台工作线程退出的时候触发RunWorkerCompleted事件

注意点:
对于控件的操作一般是放在ProgressChanged事件中,首先举个错误的例子:

//改变textbox中的值,这种会报异常:从不是创建它的线程访问
 private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;   
            for (int i = 0; i < 100; i++)
            {
                textBox1.Text = i.ToString();   
            }
        }

正确写法是:

 private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;   
            for (int i = 0; i < 100; i++)
            {
                worker.ReportProgress(i);
                System.Threading.Thread.Sleep(100); 
            }
        }
  private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
           textBox1.Text=e.ProgressPercentage.ToString();   
        }

而且我们要充分利用ProgressChanged中的e.ProgressPercentage属性:

bgWorker.ReportProgress(i);//将触发ProgressChanged事件
private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
           
            if (e.ProgressPercentage < 2000)
            {
                listBox1.Items.Add("hello world");
            }
            else if (e.ProgressPercentage > 2000 && e.ProgressPercentage < 4000)
            {
                listBox1.Items.Add("hi Lalisa");
            }
            else if (e.ProgressPercentage > 4000 && e.ProgressPercentage < 6000)
            {
                listBox1.Items.Add("hi Simon");
            }
            else if (e.ProgressPercentage > 6000 && e.ProgressPercentage < 8000)
            {
                listBox1.Items.Add("hi Rechard");
            }
            else
            {
                listBox1.Items.Add("hi EveryOne");
            }
        }

再举个switch case例子:

 private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            switch (e.ProgressPercentage)
            {
                case 0:
                    Msg((string)e.UserState);
                    break;
                case 1:
                    string[] jpgfiles = e.UserState as string[];
                    Panel panel = new Panel() { Size = new Size(120, 20), BackColor = Color.White };
                    Label count = new Label() { Text = "0", Size = new Size(45, 18), TextAlign = ContentAlignment.MiddleRight };
                    Label total = new Label() { Text = " / " + jpgfiles.Length, Size = new Size(80, 18), Location = new Point(45, 0), TextAlign = ContentAlignment.MiddleLeft };
                    panel.Controls.Add(count);
                    panel.Controls.Add(total);
                    flpUI.Controls.Add(panel);
                    break;
                case 2:
                    flpUI.Controls[e.ProgressPercentage - 2].Controls[0].Text = ((int)e.UserState).ToString();
                    break;
                case 3:
                    flpUI.Controls[e.ProgressPercentage - 2].Controls[0].Text = ((int)e.UserState).ToString();
                    break;
                case 4:
                    flpUI.Controls[e.ProgressPercentage - 2].Controls[0].Text = ((int)e.UserState).ToString();
                    break;
            }
        }

2.BackgroundWorker例程1

在这里插入图片描述

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

namespace WinForm_backgroundworker
{
    public partial class Form2 : Form
    {
        //创建BackgroundWorker的对象
        BackgroundWorker bgWorker = new BackgroundWorker();
        public Form2()
        {
            InitializeComponent();
            //设置属性
            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;
            //创建事件
            bgWorker.DoWork += BgWorker_DoWork;
            bgWorker.ProgressChanged += BgWorker_ProgressChanged;
            bgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
        }

        private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar1.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)
        {
            progressBar1.Value= e.ProgressPercentage;
           

        }

        private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;//as表示类型转换,如果能够转换则返回对应的对象,否则返回一个null
            for (int i = 0; i < 10; i++)
            {
                //如果应用程序已请求取消后台操作,CancellationPending为 true;否则为 false。 默认值为 false。
                //当为true时候,则说明CancelAsync该方法已被调用。
                if (bgWorker.CancellationPending)
                {
                    e.Cancel = true;//执行完这句代码,e.Cancelled==true;
                    break;//工作线程退出的时候触发RunWorkerCompleted事件
                }
                else
                {
                    bgWorker.ReportProgress(i * 10);//将触发ProgressChanged事件
                    System.Threading.Thread.Sleep(1000);

                }
            }
        }

        private void btnProcess_Click(object sender, EventArgs e)
        {
            if (bgWorker.IsBusy != true)//检查后台任务是否正在运行,如果不运行的话执行下面这个方法
            {
                bgWorker.RunWorkerAsync();//获取后台线程并且执行DoWork事件处理程序
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            bgWorker.CancelAsync(); //将CancellationPending属性设置为true,如果WorkerSupportsCancellation=false,运行这句代码会报错
        }
    }
}

3.BackgroundWorker例程2

在这里插入图片描述

2.代码

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

namespace WinForm_backgroundworker
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            InitializeBackgroundWorker();
        }
        private void InitializeBackgroundWorker()
        {

            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;
            bgWorker.DoWork += BgWorker_DoWork;
            bgWorker.ProgressChanged += BgWorker_ProgressChanged;
            bgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
        }

        private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled == true)
            {
                label1.Text = "Canceled!";
            }
            else if (e.Error != null)
            {
                label1.Text = "Error: " + e.Error.Message;
            }
            else
            {
                label1.Text = "Done!";
            }
        }

        private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
            string per = e.ProgressPercentage.ToString();
            label1.Text = "处理进度:" + per+"%";
        }

        private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 0; i <= 100; i++)
            {
                //如果应用程序已请求取消后台操作,CancellationPending为 true;否则为 false。 默认值为 false。
                //当为true时候,则说明CancelAsync该方法已被调用。
                if (worker.CancellationPending)//当点击
                {
                    e.Cancel = true;
                    break;
                }
                else
                {
                    System.Threading.Thread.Sleep(50);
                    worker.ReportProgress(i);
                  
                }
            }
         
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            if (bgWorker.IsBusy != true)
            {
                //该方法允许传递一个Object类型的参数到后台操作中,并且可以通过DoWork事件的DoWorkEventArgs.Argument属性将该参数提取出来。
                bgWorker.RunWorkerAsync("Hello World");
            }

        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            if (bgWorker.WorkerSupportsCancellation == true)
            {
                bgWorker.CancelAsync();
            }
        }
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中的BackgroundWorker是一个非常实用的组件,它可以在后台线程中执行耗时的操作,同时又不会阻塞UI线程,从而保证程序的流畅性和响应速度。以下是使用BackgroundWorker的一些基本步骤: 1. 引入命名空间 在C#代码中引入System.ComponentModel命名空间,以便使用BackgroundWorker组件。 ```csharp using System.ComponentModel; ``` 2. 创建BackgroundWorker对象 在窗体的类中创建一个BackgroundWorker对象,并设置它的一些属性。例如,设置WorkerReportsProgress为true,表示后台线程可以向UI线程报告进度信息;设置WorkerSupportsCancellation为true,表示后台线程可以取消操作。 ```csharp private BackgroundWorker worker = new BackgroundWorker(); public Form1() { InitializeComponent(); // 设置BackgroundWorker属性 worker.WorkerReportsProgress = true; worker.WorkerSupportsCancellation = true; // 绑定事件处理方法 worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); } ``` 3. 编写后台操作方法 在DoWork事件处理方法中编写后台操作的代码。这里需要注意的是,这个方法是在后台线程中执行的,不能直接访问UI控件,否则会引发线程异常。 ```csharp private void worker_DoWork(object sender, DoWorkEventArgs e) { // 执行后台操作 for (int i = 0; i < 100; i++) { // 向UI线程报告进度 worker.ReportProgress(i); // 如果后台线程被取消了,则立即退出 if (worker.CancellationPending) { e.Cancel = true; return; } // 模拟耗时操作 Thread.Sleep(100); } // 设置操作结果 e.Result = "操作成功"; } ``` 4. 处理进度更新事件 在ProgressChanged事件处理方法中更新UI界面的进度显示。这个方法是在UI线程中执行的,可以直接访问UI控件。 ```csharp private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { // 更新进度条的值 progressBar1.Value = e.ProgressPercentage; } ``` 5. 处理操作完成事件 在RunWorkerCompleted事件处理方法中处理操作完成后的逻辑。这个方法也是在UI线程中执行的,可以直接访问UI控件。 ```csharp private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { // 操作被取消了 label1.Text = "操作被取消了"; } else if (e.Error != null) { // 操作发生了异常 label1.Text = "操作发生了异常:" + e.Error.Message; } else { // 操作成功完成 label1.Text = "操作成功完成:" + e.Result.ToString(); } } ``` 6. 启动后台操作 在需要执行耗时操作的地方,调用BackgroundWorker的RunWorkerAsync方法启动后台操作。 ```csharp private void button1_Click(object sender, EventArgs e) { // 启动后台操作 worker.RunWorkerAsync(); } ``` 7. 取消后台操作 如果需要取消后台操作,调用BackgroundWorker的CancelAsync方法。 ```csharp private void button2_Click(object sender, EventArgs e) { // 取消后台操作 worker.CancelAsync(); } ``` 以上就是使用C#BackgroundWorker的基本步骤,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值