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

时间: 2024-07-30 13:50:40

BackgroundWorker与线程使用的相关文章

WPF 线程 Dispatcher

WPF 应用程序从两个线程开始: 一个用于处理呈现 一个用于管理 UI 呈现线程有效地隐藏在后台运行,而UI线程则接收输入.处理事件.绘制屏幕以及运行应用程序代码. 大多数应用程序都使用一个 UI 线程,但在某些情况下,最好使用多个线程.我们将在后面举例说明这一点. UI 线程对一个名为 Dispatcher 的对象内的工作项进行排队. Dispatcher基于优先级选择工作项,并运行每一个工作项,直到完成.每个UI线程都必须至少有一个Dispatcher,并且每个 Dispatcher 都只能

C#中的线程(一)入门

C#中的线程(一)入门 - wota - 博客园 公告 文章系参考转载,英文原文网址请参考:http://www.albahari.com/threading/ 作者 Joseph Albahari,  翻译 Swanky Wu 本系列文章可以算是一本很出色的C#线程手册,思路清晰,要点都有介绍,看了后对C#的线程及同步等有了更深入的理解. 入门 概述与概念 创建和开始使用多线程 线程同步基础 同步要领 锁和线程安全 Interrupt 和 Abort 线程状态 等待句柄 同步环境 使用多线程

(转载)C#线程(一)

Coding Life   28 Posts :: 0 Stories :: 91 Comments :: 0 Trackbacks 公告 <div id="blog-sidecolumn"></div><script type="text/javascript">loadBlogSideColumn();</script> C#中的线程(一)入门 <div class="postText"&

进程、线程和多线程的概念

1. 什么是进程 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源,而一个进程又是由多个线程所组成的. 2. 什么是线程 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针.程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数. 3. 什么是多线程 多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务. 4. 多线程的好处 可以提高CPU

C#线程入门(一)

入门 概述与概念 创建和开始使用多线程 线程同步基础 同步要领 锁和线程安全 Interrupt 和 Abort 线程状态 等待句柄 同步环境 使用多线程 单元模式和Windows Forms BackgroundWorker类 ReaderWriterLock类 线程池 异步委托 计时器 局部储存 高级话题 非阻止同步 Wait和Pulse Suspend和Resume 终止线程 一.入门 1.     概述与概念 C#支持通过多线程并行地执行代码,一个线程有它独立的执行路径,能够与其它的线程

C#中的线程(三) 使用多线程

第三部分:使用多线程 1.  单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM——Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留下的模型,但很多时候它也会突然出现,这是因为有必要 与旧的API 进行通信.单元模式线程与Windows Forms最相关,因为大多Windows Forms使用或包装了长期存在的Win32 API——连同它的单元传统. 单元是多线程的逻辑上的“容器”,单元产生两种容量——“单的”和“多的”.单线

线程(转载)

线程(一) 文章系参考转载,英文原文网址请参考:http://www.albahari.com/threading/ 作者 Joseph Albahari,  翻译 Swanky Wu 中文翻译作者把原文放在了"google 协作"上面,GFW屏蔽,不能访问和查看,因此我根据译文和英文原版整理转载到园子里面. 本系列文章可以算是一本很出色的C#线程手册,思路清晰,要点都有介绍,看了后对C#的线程及同步等有了更深入的理解. 入门 概述与概念 创建和开始使用多线程 线程同步基础 同步要领

winform-UI跨线程常用方法

出处:http://www.tuicool.com/articles/FNzURb http://www.cnblogs.com/smileberry/p/3912918.html 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种: 1. 通过UI线程的SynchronizationContext的Post/Send方法更新: 2. 通过UI控件的Inv

C#中的线程(一)入门

C#中的线程(一)入门 Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslator: Swanky WuPublished: http://www.cnblogs.com/txw1958/Download:http://www.albahari.info/threading/threading.pdf 第一部分:入门 概述与概念 C#支持通过多线程并行地执行代码,一个线程有它独立的执行