winform+BackgroundWorker 多线程下如何停止和暂停 您所在的位置:网站首页 线程怎么启动怎么停止 winform+BackgroundWorker 多线程下如何停止和暂停

winform+BackgroundWorker 多线程下如何停止和暂停

2023-09-21 10:33| 来源: 网络整理| 查看: 265

本文主要记录如何利用winform,BackgroundWorker线程控件和progressBar进度控件进行开发(这样启用工作线程和UI主线程,可以让进度条能进行更新,避免UI假死),同时支持启用多个后台BackgroundWorker,以及支持统一的全局进度条更新,同时支持暂停和停止任务。

下面是定义BackgroundWorker各种事件:

BackgroundWorker Bworker = new BackgroundWorker(); Bworker.WorkerReportsProgress = true; Bworker.DoWork += new DoWorkEventHandler(worker_DoWork); Bworker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); Bworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); Bworker.RunWorkerAsync();

在work_DoWork中调用具体执行的方法,worker_ProgressChanged方法用来实时更新进度条值,worker_RunWorkerCompleted方法用来处理当后台线程执行完操作后要处理的事情,如更新界面UI进度条等。

刚开始的时候是没有取消按钮的,现在看看怎么加上取消按钮。

BackgroundWorker 是支持取消事件的,主要通过一个button_click事件,调用Bworker .CancelAsync(),然后在worker_DoWork中检测是否已经取消了:

//检测是否被取消了 if (worker.CancellationPending) { e.Cancel = true; break; }

       有了取消,就想起了也需要加上暂停,暂停的功能需要自己实现。其实就是利用ManualResetEvent 允许线程通过发信号互相通信的特点,

1.设定一个全局的变量,  public static ManualResetEvent mre = new ManualResetEvent(false);ManualResetEvent建立时是把false作为start的初始状态,这个类用于通知另一个线程,让它等待一个或多个线程。

2.增加一个暂停Pause_Click事件,如果是暂定,则调用 mre.Reset();//暂停当前线程的工作,发信号给waitOne方法,阻塞。

   如果是继续,则 mre.Set();//继续某个线程的工作,

   worker_DoWork中检测mre.WaitOne();这样就完成了简单的暂停控制。

     上面还是用单个线程处理事务,速度很慢,CPU,内存,IO都没有充分的利用起来,所以下面就想到了启用多线程,充分利用系统资源。

      那么问题来了,如何结合BackgroundWorker使用多线程呢,后来发现其实一个简单的做法,就是启用多个BackgroundWorker来启动业务,当然,对应的ManualResetEvent也需要有多个。(启用多个BackgroundWorker唯一要注意的是更新全局变量进度的时候,需要针对进度进行加锁)

private List lstManualResets = null; private BackgroundWorker Bworker = null; private static readonly object objLock = new object(); for (int i = 0; i < nThreadNum; i++) { Bworker = new BackgroundWorker(); Bworker.WorkerSupportsCancellation = true; Bworker.WorkerReportsProgress = true; Bworker.DoWork += new DoWorkEventHandler(worker_DoWork); Bworker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged); Bworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); lstBworkers.Add(Bworker); lstManualResets.Add(new ManualResetEvent(true)); Bworker.RunWorkerAsync(i); }

一个临时转换工具的开发过程,记录下来,如上有什么更好建议或想法,也请大家多多指点。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有