BackgroundWorker处理多线程问题
每当我们需要处理一下比较耗时的操作时,如下载/删除大量数据、重载UI界面时,如果只使用单线程会出现一段时间的假死状态,用传统的Thread来处理对第一次接触多线程的同学并不友好(例如我),因此可以使用C#自带的BackGroundWorker类来解决问题,比较方便:
1.先包含必要的类
> using System.ComponentModel;
2.实例代码如下:
载入时先把这两个属性设置一下:
backgroundWorker1.WorkerReportsProgress = true;//报告进度更新
backgroundWorker1.WorkerSupportsCancellation = true;//是否支持取消该异步操作
private void BtnStart_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
}
3.可用CancelAsync取消此操作
private void BtnCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
}
}
4.BackGroundWorker涉及到3个事件(也是仅有的3个特有的事件分别是:DoWork/ProgressChanged/RunWorkerCompleted)
1)DoWork(加粗方法触发ProgressChanged)
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
if (worker == null) return;
for (var i = 1; i <= 10; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
// Perform a time consuming operation and report progress.
System.Threading.Thread.Sleep(500);
worker.**ReportProgress**(i * 10);
}
}
}
2)ProgressChanged(接受DoWork传来的数据后可以展现到前台)
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
resultLabel.Text = e.ProgressPercentage + "%";
}
3)RunWorkerCompleted(完成、手动取消均可触发)
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true)
{
resultLabel.Text = "Canceled!";
}
else if (e.Error != null)
{
resultLabel.Text = "Error: " + e.Error.Message;
}
else
{
resultLabel.Text = "Done!";
}
}