• 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

  • 相关阅读:
    日期计算
    普通二叉树转换成搜索二叉树
    每周行情
    virtualbox安装增强功能时【未能加载虚拟光盘】
    linux实用命令之如何移动文件夹及文件下所有文件
    Linux文件夹文件创建、删除
    php 克隆 clone
    function_exists (),method_exists()与is_callable()的区别
    webgrind安装使用详细说明
    windows下redis的安装配置和php扩展使用phpredis
  • 原文地址:https://www.cnblogs.com/Opiece/p/4787487.html
Copyright © 2020-2023  润新知