在.net框架下,实现异步处理的方式主要有三种。一是采用beginXXX和endXXX来实现,一种利用多线程Thread实现。另外,利用BackgroundWork组件来实现。下面对BackgroundWork组件的使用进行一下研究。
BackgroundWork是基于事件驱动的,所以使用起来要比APM方便使用过的应该知道,我们只需要只需要绑定3个事件,就能很轻松的完成复杂的异步操作,并且可以轻松获取执行的进度、取消执行等功能。下面就具体看看他的内部实现。为我们实现自己的异步功能也有所帮助。
(1)BackgroundWork代码结构
代码中定义了DoWork、ProgressChanged、RunWorkerCompleted这三个事件,我们在使用时也只用把方法注册到时间上就行了。
(2)实例
public partial class backGroundWorkTest : Form
{
private int maxBar;
public backGroundWorkTest()
{
InitializeComponent();
button1.Enabled = true;
button2.Enabled = false;
//允许报告进程
backgroundWorker1.WorkerReportsProgress = true;
//支持取消操作
backgroundWorker1.WorkerSupportsCancellation = true;
maxBar = 100;
progressBar1.Maximum = maxBar;
}
//启动
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(maxBar);//传递参数
button1.Enabled = false;
button2.Enabled = true;
}
//DoWork
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
e.Result = dealBackWork(backgroundWorker1, e);//将含有参数的e又传递给dealBackWork,操作完成后,又对其的Result赋值
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//耗时的后台操作,独立线程,不能在此调用主线程控件
private string dealBackWork(BackgroundWorker worker, DoWorkEventArgs e)
{
int maxRecords = (int)e.Argument;//获取传递的参数
int percent = 0;
for (int i = 0; i < maxRecords; i++)
{
//执行过程中判断用户是否取消操作
if (worker.CancellationPending)
return i.ToString();
percent = (int)(((double)i / (double)maxRecords) * 100);
//向主线程报告进度
worker.ReportProgress(percent, new KeyValuePair<int, string>(i, Guid.NewGuid().ToString()));
Thread.Sleep(100);
}
return maxRecords.ToString();
}
//主线程操作,进度改变时激发
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
KeyValuePair<int, string> temppair = (KeyValuePair<int, string>) e.UserState;
progressBar1.Value = temppair.Key;
label1.Text = temppair.Value;
}
//主线程操作,后台运行完成时激发
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("完成到:" + e.Result.ToString());
button1.Enabled = true;
button2.Enabled = false;
}
//取消
private void button2_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
}