zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    HDU 3401 Trade
    POJ 1151 Atlantis
    HDU 3415 Max Sum of MaxKsubsequence
    HDU 4234 Moving Points
    HDU 4258 Covered Walkway
    HDU 4391 Paint The Wall
    HDU 1199 Color the Ball
    HDU 4374 One hundred layer
    HDU 3507 Print Article
    GCC特性之__init修饰解析 kasalyn的专栏 博客频道 CSDN.NET
  • 原文地址:https://www.cnblogs.com/Opiece/p/4787487.html
Copyright © 2011-2022 走看看