[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();
            }
        }
    }
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1768317420

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值