介绍
详见:
https://www.cnblogs.com/sparkdev/p/5906272.html
缺点:只能在 Form 中使用,复杂情况用 Task
添加 BackgroundWorker
代码
private BackgroundWorker _demoBGWorker = new BackgroundWorker();
设计器方式
更新UI
如果要更新UI,把 WorkerReportsProgress 属性设置为 true,否则报错
代码设置
_demoBGWorker.WorkerReportsProgress = true;
设计器设置
添加 DoWork 事件
在 DoWork 事件处理函数中执行 耗时任务
注意:不能直接访问控件、直接获取控件值,会报错 (需要额外代码)
代码添加
_demoBGWorker.DoWork += BGWorker_DoWork;
设计器添加
事件代码
private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
//在这里执行耗时的运算。
int sum = 0;
for (int i = 0; i <= 100; i++)
{
sum += i;
string message = "Current sum is: " + sum.ToString();
//ReportProgress() 方法把信息传递给 ProcessChanged 事件处理函数。
//第一个参数类型为 int,表示执行进度。
//如果有更多的信息需要传递,可以使用 ReportProgress 的第二个参数
bgWorker.ReportProgress(i, message);
Thread.Sleep(600);
}
}
添加 ProgressChanged 事件
然后指定 ProgressChanged 事件处理方法,用于更新UI
代码添加
_demoBGWorker.ProgressChanged += BGWorker_ProgressChanged;
设计器添加
事件代码
private void BGWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// 取出 ReportProgress() 方法的第一个参数,修改进度条
this.progressBarSum.Value = e.ProgressPercentage;
// 使用 e.UserState ,获取 ReportProgress() 方法的第二个参数
string message = e.UserState.ToString();
}
调用 RunWorkerAsync() 方法启动
_demoBGWorker.RunWorkerAsync();
调用该方法后,开始执行 BGWorker_DoWork()
高级用法1-传参给 DoWork() 事件函数
调用 RunWorkerAsync() 方法传参给 DoWork() 事件处理函数
调用 RunWorkerAsync() 方法时传 100
_demoBGWorker.RunWorkerAsync(100);
private void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
int endNumber = 0;
if(e.Argument != null)
{
// 取出 100
endNumber = (int)e.Argument;
}
}
高级用法2-传参给 ProgressChanged() 事件函数
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
progressForm.initProgressBar(10);
// 设置进度,并且传参数
backgroundWorker2.ReportProgress(1,"哈哈");
}
private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// 取出参数
string result = (string)e.UserState;
if (result != null)
{
}
}
高级用法3-传参给 RunWorkerCompleted() 事件函数
BackgroundWorker 的 RunWorkerCompleted 事件可以通过 RunWorkerCompletedEventArgs 参数接收后台操作返回的值。以下是实现方式:
在
DoWork事件处理程序中,将结果赋值给DoWorkEventArgs.Result属性在
RunWorkerCompleted事件处理程序中,通过e.Result获取该值
示例代码如下:
提示: BackgroundWorker1_RunWorkerCompleted() 方法处理是有顺序的
using System;
using System.ComponentModel;
using System.Windows.Forms;
public class ExampleForm : Form
{
private BackgroundWorker backgroundWorker1;
public ExampleForm()
{
// 初始化 BackgroundWorker
backgroundWorker1 = new BackgroundWorker();
backgroundWorker1.DoWork += BackgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += BackgroundWorker1_RunWorkerCompleted;
// 启动后台操作
backgroundWorker1.RunWorkerAsync();
}
// 后台操作
private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// 执行耗时操作
string result = LongRunningOperation();
// 将结果存储在 e.Result 中
e.Result = result;
}
// 后台操作完成后执行
private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// 检查是否有错误,如果 “获取后台操作返回的值” 在上面,当程序报错时,程序会出现异常
if (e.Error != null)
{
MessageBox.Show($"发生错误: {e.Error.Message}");
return;
}
// 检查是否取消了操作
if (e.Cancelled)
{
MessageBox.Show("操作已取消");
return;
}
// 获取后台操作返回的值
string result = e.Result as string;
if (result != null)
{
MessageBox.Show($"操作完成,结果: {result}");
}
}
// 模拟耗时操作
private string LongRunningOperation()
{
// 模拟耗时工作
System.Threading.Thread.Sleep(3000);
return "这是后台操作的结果";
}
}
上述代码中:
DoWork事件处理程序中执行后台操作,并将结果存储在e.Result中RunWorkerCompleted事件处理程序中通过e.Result获取结果- 可以传递任何类型的对象,不仅仅是字符串
- 记得处理可能的错误和取消情况
如果需要传递多个值,可以使用自定义类、匿名类型或 Tuple 来包装多个值。
高级用法4-取消
执行耗时任务时,实现取消当前任务
设置属性
必须设置下面属性为 true 才能使用 取消 功能:
bgWorker.WorkerSupportsCancellation = true;
修改BGWorker_DoWork方法
在 DoWork 方法的 for 循环中,定期检查 CancellationPending 属性,如果为 true 表示取消
Thread.Sleep(600) 后面添加代码,如下:
bgWorker.ReportProgress(i, message);
Thread.Sleep(600);
//在操作的过程中需要检查用户是否取消了当前的操作。
if (bgWorker.CancellationPending == true)
{
e.Cancel = true;
break;
}
取消按钮的事件代码
点击取消按钮时要调用的代码:
bgWorker.CancelAsync();
处理取消结果
在 RunWorkerCompleted 事件中通过 e.Cancelled 判断是否为取消状态:
if (e.Cancelled)
{
// 处理取消逻辑
}
高级用法5-执行结束、异常处理
指定 RunWorkerCompleted 事件处理函数
_demoBGWorker.RunWorkerCompleted += BGWorker_RunWorkerCompleted;
private void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//如果用户取消了当前操作就关闭窗口。
if (e.Cancelled)
{
this.Close();
}
//计算已经结束,需要禁用取消按钮。
this.btnCancel.Enabled = false;
//计算过程中的异常会被抓住,在这里可以进行处理。
if (e.Error != null)
{
Type errorType = e.Error.GetType();
switch (errorType.Name)
{
case "ArgumentNullException":
case "MyException":
//do something.
break;
default:
//do something.
break;
}
}
//计算结果信息:e.Result
//use it do something.
}
RunWorkerCompleted 事件处理函数会在DoWork 事件处理函数返回后被调用。通过它我们可以进行一些运算结束后的操作,比如禁用取消按钮,异常处理,结果显示等。
注意
如果想要拿到 e.Result,需要在 BGWorker_DoWork() 方法中设置 e.Result属性,如:
e.Result = sum;




