BackgroundWorker与线程使用

  在一个程序中,一些耗时的操作,在长时间运行时可能会导致用户界面 (UI) 处于停止响应状态,用户在这操作期间无法进行其他的操作,为了不使UI层处于停止响应状态,需要将这些耗时的操作,设置为后台线程,并且在UI层可以展示后台操作的进度,比较常用的方法有使用线程以及BackgroundWorker类。

  1、线程方法

  当我们要在前太展示后台的操作进程时,是不允许跨线程访问控件。此时需要取消控件的跨线程访问,在winform中可以设置CheckForIllegalCrossThreadCalls = false,而在wpf中不存在CheckForIllegalCrossThreadCalls 这个属性,在这介绍一种方法,取消跨线程访问,在wpf中有Dispatcher属性使用委托的方法来告诉控件需要做什么。

 public Action<int> proBarDel;//先定义一个委托

 /// <summary>
        /// 取消夸线程访问
        /// </summary>
        /// <param name="str"></param>
        private void CrossThread(int  i)
        {
            //取消控件夸线程访问
            
            proBarDel = this.GetReceive;
            this.pb.Dispatcher.Invoke(proBarDel, i);
            this.lab1.Dispatcher.Invoke(proBarDel, i);
        }

  /// <summary>
        /// 为控件设置内容
        /// </summary>
        /// <param name="receiveStr"></param>
        public void SetValue(int receive)
        {
            pb.Value = receive;
            lab1.Content = receive;
        }

//在按钮的点击事件中新增一个线程

     Thread th = new Thread(() => {
    for (int i = 0; i <= 100; i++)
    {
      CrossThread(i);//将执行的进度汇报给UI层的控件
      Thread.Sleep(100);
    }
  });
  th.IsBackground = true;
  th.Start();

 

当点击开始按钮时进度条就会显示进度

2、使用BackgroundWorker

BackgroundWorker 类允许在单独的专用线程上运行操作,使用BackgroundWorker 需要引用System.ComponentModel

BackgroundWorker 有三个重要的事件

this.bgWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
this.bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
this.bgWorker.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);

DoWork(),将需要处理的后台操作放入DoWork()中

       BackgroundWorker bgWorker = new BackgroundWorker();//创建一个BackgroundWorker

///
<summary> /// 需要处理的事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { e.Result = DoWork(bgWorker, e); } private bool DoWork(BackgroundWorker bk,DoWorkEventArgs e) { int num = (int)e.Argument;// int p = 0; for (int i = 0; i < num; i++) { if (bk.CancellationPending)//判断是否取消后台操作 { return false; } else { p = (int)(((double)i / (double)num )* 100); bk.ReportProgress(p);//报告进度 Thread.Sleep(100); } } return true; }

ProgressChanged调用 ReportProgress 时发生

 private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

            proBar.Value = e.ProgressPercentage;//获得进度给进度条
            this.lab1.Content = e.ProgressPercentage;
        }

RunWorkerCompleted 后台操作执行完成时或取消时发生

 /// <summary>
        /// 处理完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("ok");
        }

在使用BackgroundWorker 报告后台的进度时需要将 WorkerReportsProgress 设置为true,否则在bk.ReportProgress(p)报告进度是会抛出异常

以上只是个人使用的总结,不是很全面,希望大家补充,有错误的地方希望能够指出

在MSDN中有对BackgroundWorker的详细的讲解https://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.aspx

原文地址:https://www.cnblogs.com/Opiece/p/4787487.html