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();
}
}
}
}