天天看点

BackgroundWorker 实现的多线程操作

BackgroundWorker组件介绍

BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。
           

常用方法

  1. RunWorkerAsync 开始执行后台操作。引发 DoWork 事件
  2. CancelAsync 请求取消挂起的后台操作。注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查CancellationPending 属性,来决定是否要继续执行耗时的操作。
  3. ReportProgress引发 ProgressChanged 事件。

常用属性

  1. CancellationPending 指示应用程序是否已请求取消后台操作。只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。
  2. WorkerSupportsCancellation指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。
  3. WorkerReportsProgress指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。
注意:
  • 在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和RunWorkerCompleted 事件与用户界面进行通信。
  • 如果想在 DoWork 事件处理程序中和用户界面的控件通信,可在用 ReportProgress 方法。ReportProgress(int percentProgress, object userState),可以传递一个对象。ProgressChanged 事件可以从参数ProgressChangedEventArgs 类的UserState 属性得到这个信息对象。这个事件也可以实现进度条功能,把任务的进度实时呈现给用户。
  • 简单的程序用BackgroundWorker 比 Thread 方便,Thread中和用户界面上的控件通信比较麻烦,需要用委托来调用控件的 Invoke 或BeginInvoke 方法,没有 BackgroundWorker 方便。

实例

public partial class Analyse : Form
 {
	    public Analyse()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;  //线程间操作无效: 从不是创建控件“XXX”的线程访问它。
        }

		/// <summary>
        /// Analyse
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Analyse_btn_Click(object sender, EventArgs e)
        {
            try
            {
                // 数据分析
                if (!bgWorker_Process.IsBusy)
                {
                    AnalyseResults = new List<AnalyseResultMdl>();
                    this.bgWorker_Process = new BackgroundWorker()  //new一个新的,避免重复添加相同和其他无用DoWork,也可以不用new
                    {
                        WorkerReportsProgress = true  //能否报告进度更新
                    };
                    this.bgWorker_Process.DoWork += new DoWorkEventHandler(Analyse_DoWork);
                    this.bgWorker_Process.ProgressChanged += new ProgressChangedEventHandler(bgWorker_Process_ProgressChanged);
                    this.bgWorker_Process.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_Process_RunWorkerCompleted);
                    this.bgWorker_Process.RunWorkerAsync(); // 运行 backgroundWorker 组件
                }
                else
                {
                    MessageBox.Show($"等待其他操作完成再执行...");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"分析出错:{ex}");
            }
        }

		/// <summary>
        /// Analyse_DoWork
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Analyse_DoWork(object sender, EventArgs e)
        {
        	int intPercentage=1;
			foreach (var item in itemList)
			{
				bgWorker_Process.ReportProgress(Convert.ToInt32(Math.Floor(Convert.ToDouble(intPercentage * 100 / BaseDataList.Count()))));   // 触发bgWorker_Process.ProgressChanged事件
				// 耗时操作
				// 。。。
				intPercentage++;
			}
        }

		/// <summary>
        /// 进度变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
		private void bgWorker_Process_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;  //progressBar1 进度条控件
        }
        
        /// <summary>
        /// 程序执行完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bgWorker_Process_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message);
            }
            else if (e.Cancelled)
            {
            }
            else
            {
                this.bgWorker_Process.Dispose();
            }
        }
 }

           
END