BackgroundWorker是用于在后台执行耗时操作,同时允许更新UI的组件,这样可以避免界面卡住。
步骤:
1.创建程序,添加控件
- 创建一个Windows Forms应用程序
- 添加ProgressBar控件,
- 添加按钮:开始、暂停、继续、取消
- 添加BackgroundWorker组件(控件),设置其WorkerReportsProgress和WorkerSupportsCancellation属性为true,使其支持报告进度和支持取消操作。
窗体设计代码如下
private ProgressBar progressBar;
private Button btnStart;
private Button btnPause;
private Button btnResume;
private Button btnCancel;
private Label lblStatus;
// 初始化代码(示例布局):
this.progressBar = new ProgressBar();
this.btnStart = new Button();
this.btnPause = new Button();
this.btnResume = new Button();
this.btnCancel = new Button();
this.lblStatus = new Label();
// 设置控件属性和位置(略)
2. 初始化BackgroundWorker,设置属性。
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace BackgroundWorkerExample
{
public partial class MainForm : Form
{
private BackgroundWorker backgroundWorker; //用控件也可以的! 在工具栏里面可以直接添加这个控件,对照设置控件的属性就行了!
private ManualResetEvent pauseEvent = new ManualResetEvent(true); // 控制暂停的同步对象
private bool isPaused = false;
public MainForm()
{
InitializeComponent();
InitializeBackgroundWorker();
UpdateButtonStates(false);
}
private void InitializeBackgroundWorker()
{
backgroundWorker = new BackgroundWorker
{
WorkerReportsProgress = true, // 允许报告进度
WorkerSupportsCancellation = true // 允许取消操作
};
// 绑定事件处理器
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
}
3. 实现DoWork事件,处理任务循环,进度报告,暂停和取消。
// 模拟耗时任务(在后台线程运行)
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
}
pauseEvent.WaitOne(); // 检查是否被暂停
// 模拟工作(例如处理文件、计算等)
Thread.Sleep(50);
// 报告进度百分比
backgroundWorker.ReportProgress(i);
}
}
4. 处理ProgressChanged事件更新进度条。
// 更新进度条(在主线程运行)
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
lblStatus.Text = $"Progress: {e.ProgressPercentage}%";
}
5. 处理RunWorkerCompleted事件恢复UI状态
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
lblStatus.Text = "Operation canceled!";
}
else if (e.Error != null)
{
lblStatus.Text = $"Error: {e.Error.Message}";
}
else
{
lblStatus.Text = "Completed!";
}
progressBar.Value = 0;
UpdateButtonStates(false);
isPaused = false;
pauseEvent.Set(); // 确保重置暂停状态
}
6. 按钮的事件处理函数,控制BackgroundWorker和ManualResetEvent。
// 更新按钮可用状态
private void UpdateButtonStates(bool isWorking)
{
btnStart.Enabled = !isWorking;
btnPause.Enabled = isWorking && !isPaused;
btnResume.Enabled = isWorking && isPaused;
btnCancel.Enabled = isWorking;
}
// 按钮事件处理
private void btnStart_Click(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
{
backgroundWorker.RunWorkerAsync();
UpdateButtonStates(true);
}
}
private void btnPause_Click(object sender, EventArgs e)
{
if (isPaused) return;
isPaused = true;
pauseEvent.Reset(); // 阻塞后台线程
UpdateButtonStates(true);
}
private void btnResume_Click(object sender, EventArgs e)
{
if (!isPaused) return;
isPaused = false;
pauseEvent.Set(); // 恢复后台线程
UpdateButtonStates(true);
}
private void btnCancel_Click(object sender, EventArgs e)
{
if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();
pauseEvent.Set(); // 确保取消时不会死锁
}
}