BackgroundWorker 的输入、输出参数、进度条与文字刷新、取消机制、返回事件
1. 定义全局变量
BackgroundWorker backgroundwoker;
2. 点击开始按钮或其它时机初始化
backgroundwoker = new BackgroundWorker();
backgroundwoker.WorkerSupportsCancellation = true;//允许中途取消进程
backgroundwoker.WorkerReportsProgress = true;
backgroundwoker.DoWork += new DoWorkEventHandler(BkWorkRun); //启动异步进程事件
backgroundwoker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BkWorkCompleted); //完成事件
backgroundwoker.ProgressChanged += new ProgressChangedEventHandler(BkProgressChanged); //刷新进度条及所有相关界面控件事件
backgroundwoker.RunWorkerAsync(dt); //dt是传输参数,可以是任何数据类型
3.添加异步进程事件 注意参数 DoWorkEventArgs e 包含了传输参数RunWorkerAsync(dt)中的dt
void BkWorkRun(object sender, DoWorkEventArgs e)
{
MilCvlCompare(e);
}
4.实际执行异步线程的方法
void MilCvlCompare(DoWorkEventArgs workArg)
{
//wrkArg中包括输入和输出两个参数Argument和Result,同时它的workArg.Cancel表示取消进程
DataTable dt = workArg.Argument as DataTable; //获取workArg传入参数
//进度报告,除了报告主线程进度百分比外,还可传回任何需界面显示的数据
backgroundwoker.ReportProgress(percent, new string[] { status,rescy });//第一个参数int型,必须<=100;第二个返回参数object型,可以返回任意数据
...
workArg.Result = new string[] { res, path };//设置workArg的返回参数,此参数可在CompletedEventHandler事件中使用
}
5. 进度刷新界面
void BkProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage; //刷新进度条
//刷新界面文字提示
//最好加上try catch避免用户中途关闭窗体,系统报错
try
{
string[] res = e.UserState as string[];
labInfo.Text = res[0];
if(res[1]!="")
tbOutPut.AppendText(res[1]+"\r\n\r\n"); }
catch { }
}
6. 完成事件
void BkWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Result == null)
return;
string[] res = e.Result as string[]; //获取返回值
...//处理返回值
progressBar.Visible = false;
btnParse.Enabled = true;
}
7.取消机制
//CancelAsync方法是在前台主线程用的,CancellationPending属性是在后台子线程用的。实际的使用方式应该是这样的:
private void btn_Stop_Click(object sender, EventArgs e) //点击取消按钮,前台触发CancelAsync方法
{
backgroundwoker.CancelAsync(); //提交取消命令,但还未取消
}
//这时,CancellationPending由false变为true
//再在DoWork事件里获取CancellationPending,依据它来处理后台任务,比如说直接return;
static void bw_DoWork(object sender, DoWorkEventArgs workArg)
{
if (backgroundwoker.CancellationPending) //判断是否取消操作
{
workArg.Cancel = true; //这里才真正取消
return;
}
}
//最后完成时判断
static void BkWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
MessageBox.Show("You cancelled!");
else if (e.Error != null)
MessageBox.Show("Worker exception: " + e.Error.ToString());
else
{
MessageBox.Show("Complete - " + e.Result);
}
}