使用winform BackgroundWorker组件执行多线程任务
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
bgWorker.WorkerReportsProgress = true;//报告完成进度
bgWorker.WorkerSupportsCancellation = true;//允许用户终止后台线程
bgWorker.DoWork += BgWorker_DoWork;
bgWorker.RunWorkerCompleted += BgWorker_RunWorkerCompleted;
bgWorker.ProgressChanged += BgWorker_ProgressChanged;
}
private void btnStart_Click(object sender, EventArgs e)
{
//判断backgroundWorker1是否正在运行异步操作
if (!bgWorker.IsBusy)
{
//开始执行后台异步操作,调用DoWork事件
bgWorker.RunWorkerAsync(100);
}
//等待后台运行完毕
while (bgWorker.IsBusy)
{
Application.DoEvents();
}
MessageBox.Show("操作完成");
}
private void btnStop_Click(object sender, EventArgs e)
{
if (bgWorker.WorkerSupportsCancellation)
{
bgWorker.CancelAsync();//取消后台操作
bgWorker.Dispose();//释放资源
}
}
//DoWork事件声明要执行的耗时操作
private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker backgroundWorker = sender as BackgroundWorker;
e.Result = ListNumber(backgroundWorker, e);//运算结果保存在e.Result中(在RunWorkerCompleted事件可能会使用到)
}
bool ListNumber(object sender, DoWorkEventArgs e)
{
int num = (int)e.Argument;//接收传入的参数,即RunWorkerAsync(object argument)传入的值
for (int i = 1; i <= num; i++)
{
if (bgWorker.CancellationPending)//判断是否请求了取消后台操作,如果为false则退出
{
e.Cancel = true;//e.Cancel 是否应该取消事件
return false;
}
Thread.Sleep(10);//执行一个耗时操作
bgWorker.ReportProgress(i * 100 / num, i);//报告完成进度,该方法会触发ProgressChanged事件
}
return true;
}
//ReportProgress该方法触发ProgressChanged事件,在ProgressChanged事件中接收报告完成进度参数
private void BgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;//将完成进度数据传给进度条
//label1.Text = e.ProgressPercentage + "%";
////另开一个线程上设置Label的属性
Thread thread = new Thread(delegate(object parameter)
{
SetLabel(parameter);
});
thread.Start(e.ProgressPercentage);
//将中间计算结果在ListBox控件中显示出来
listBox1.Items.Add(e.UserState);//接收ReportProgress方法传递过来的userState
}
private void BgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled == true) //e.Cancelled指示异步操作是否已被取消
{
MessageBox.Show("Canceled!");
}
else if (e.Error != null) //e.Error 指示异步操作期间发生的错误
{
MessageBox.Show("Error: " + e.Error.Message);
}
else
{
MessageBox.Show(e.Result.ToString()); //e.Result 获取异步操作结果的值,即DoWork事件中,Result设置的值。
}
}
delegate void Action(int args);//Net3.5自带的Action无参数无返回值
private void SetLabel(object ProgressPercentage)
{
int progressPercentage = 0;
int.TryParse($"{ProgressPercentage}", out progressPercentage);
Action action = delegate (int args)
{
this.label1.Text = args + "%";
};
if (this.InvokeRequired)//判断当前代码是运行于创建该控件的线程之上,还是运行于另一个线程之上。
this.Invoke(action, progressPercentage);//注意控件的Inovoke和BeginInvoke委托的方法都执行在UI线程上。对Control的Invoke方法可以使用一个简单的系统委托MethodInvoker无参数返回Void调用。
else
action(progressPercentage);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现