BackgroundWorker控件其实是对Thread的一层封装,使我们可以快速的创建一个线程,并且能够报告进度,暂停,取消以及完成后进行其他的处理,当我们需要执行一些耗时的操作,又不想让当前界面出于无响应的状态的时候,就可以考虑使用BackedWorker控件,以异步的方式来执行。
1.BackgroundWorker类介绍
1.1. 四个常用属性:
public bool IsBusy { get; } //只读属性,用来判断当前线程是否正在工作中
public bool WorkerReportsProgress { get; set; } //决定当前线程是否能报告进度
public bool WorkerSupportsCancellation { get; set; } //决定当前线程能否取消
public bool CancellationPending { get; } //只读属性,用来判断是否发送了取消线程的消息(当调用CancelAsync()方法时,被设置为true)
1.2. 三个常用事件:
public event DoWorkEventHandler DoWork; //启动线程,线程的主要逻辑,调用RunWorkerAsync()时触发该事件
public event ProgressChangedEventHandler ProgressChanged; //报告进度,如果想要和UI进行交互必须要通过这个函数
public event RunWorkerCompletedEventHandler RunWorkerCompleted; //结束,当线程运行完毕、发生异常和调用CancelAsync()方法这三种方式都会触发该事件
1.3. 三个常用方法:
public void RunWorkerAsync(); //启动线程,触发DoWork事件
public void RunWorkerAsync(object argument);
public void ReportProgress(int percentProgress); //报告进度,触发ProgressChanged事件
public void ReportProgress(int percentProgress, object userState);
public void CancelAsync(); //取消线程,将CancellationPending设置为true
2.BackgroundWorker用法
下面我们参照MSDN文档,写一个简单的Demo例程,来看看BackedWorker的用法
2.1界面布局
界面布局如下,
两个Button,一个名为startAsync,另一个名为cancelAsyn,
一个progressbar名为progressbar1
一个label名为resultLabel
当然,还必须要有一个backgroundWorker控件,名为backgroundWorker1
2.2用法示例
使用代码如下
namespace WindowsFormsApplication1
{
public partial class FormMain : Form
{
public FormMain(ArrayList arrip_list)
{
InitializeComponent();
progressBar1.Minimum = 0; //设置progressbar的最小值
progressBar1.Maximum = 100; //设置progressbar的最大值
backgroundWorker1.WorkerReportsProgress = true; //可以汇报进度,只有置true,我们才可以和UI界面进行交互,否则backgroundWorker无法操控其他控件
backgroundWorker1.WorkerSupportsCancellation = true; //可以被取消
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
}
void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//backgroundWorker结束
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//设置进度条进度和result_result来显示进度
resultLabel.Text = e.ProgressPercentage.ToString() + "%";
progressBar1.Value = e.ProgressPercentage;
}
void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
//throw new NotImplementedException();
//每间隔500ms之后,进度增加10%
//注意!由于backgroundWorker是一个后台线程,所以他没有办法直接操控其他控件
//我们必须调用ReportProgress,然后在这个函数里面才可以和UI进行交互
for (int i = 0; i <= 10; i++)
{
if (backgroundWorker1.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
System.Threading.Thread.Sleep(500);
backgroundWorker1.ReportProgress(i * 10);
}
}
}
private void startAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
backgroundWorker1.RunWorkerAsync(); //启动backgroundWorker
}
}
private void cancelAsyncButton_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
backgroundWorker1.CancelAsync(); //取消backgroundWorker
}
}
}
}
参考文献