BackgroundWorker使用入门

来源:互联网 发布:中国安检有多严格 知乎 编辑:程序博客网 时间:2024/05/16 01:22
 

 说实话,我就压根不知道有这么一个控件。今天周末实在不想干正事,打开vs2005竟然看到了这个控件,根据这个名字大概就能意识到是一个关于线程后台执行的东东,因为最近很多东西都是我自己写线程,后台运行,操作UI控件的时候自己写委托。既然microsoft自己搞了这么一个东西出来,肯定比较有意思,于是谷歌之。。。发现使用起来还是很简单。大概说一下用法。

3个函数:

DoWork:具体的线程执行的代码块,就是让这个线程做什么的,自己填充内容。。
ProgressChanged:用于更新进度的回调,比如有一个进度条,当doWork中执行了任务的时候,调用BackgroundWork的ReportProgress方法,就可以把进度报告出来,然后这个函数捕获报告的内容,进行具体的进度操作。使用该函数的话,必须将BackgroundWork的WorkerReportsProgress属性设置为true。
RunWorkerCompleted:当线程执行完内容的回调函数。

还有一个属性:WorkerSupportsCancellation 就是是否允许让线程挂起。

 

给个简单代码,这个里面包含了挂起的操作,但是里面有个地方就是挂起后,怎么接下来操作?比如恢复还是终止,我也没搞懂怎么弄,高手知道的话可以补充下:

 

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Threading;namespace BackgroundWorker{    public partial class Form1 : Form    {        int i = 0;        public Form1()        {            InitializeComponent();        }        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)        {            while (i < 10)            {                if (!((System.ComponentModel.BackgroundWorker)sender).CancellationPending)                {                    //this.textBox1.Text = i + "";                    i++;                    this.backgroundWorker1.ReportProgress(i);                    Thread.Sleep(500);                }                            }        }        private void button1_Click(object sender, EventArgs e)        {            if (backgroundWorker1.CancellationPending)            {                MessageBox.Show("正在运行还没停止");                // 这个地方如何让background停止或者            }            else            {                this.backgroundWorker1.RunWorkerAsync();            }        }        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            if (e.Cancelled)            {                this.textBox1.Text = "操作取消";            }            else            {                this.textBox1.Text = "操作完毕";            }                    }        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)        {            this.textBox1.Text = e.ProgressPercentage + "";            this.progressBar1.Value = e.ProgressPercentage;        }        private void button2_Click(object sender, EventArgs e)        {            this.backgroundWorker1.CancelAsync();        }    }}


 

 

再来从网上找来段文字补充下对BackgroundWorker的理解吧,转的哦:

在VS2005中添加了BackgroundWorker组件,该组件在多线程编程方面使用起来非常方便,然而在开始时由于没有搞清楚它的使用机制,走了不少的弯路,现在把我在使用它的过程中的经验与诸位分享一下。
    BackgroundWorker类中主要用到的有这列属性、方法和事件:
    重要属性:
    1、CancellationPending             获取一个值,指示应用程序是否已请求取消后台操作。通过在DoWork事件中判断CancellationPending属性可以认定是否需要取消后台操作(也就是结束线程);
    2、IsBusy                          获取一个值,指示 BackgroundWorker 是否正在运行异步操作。程序中使用IsBusy属性用来确定后台操作是否正在使用中;
    3、WorkerReportsProgress           获取或设置一个值,该值指示BackgroundWorker能否报告进度更新
    4、WorkerSupportsCancellation      获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。设置WorkerSupportsCancellation为true使得程序可以调用CancelAsync方法提交终止挂起的后台操作的请求;
    重要方法:
    1、CancelAsync         请求取消挂起的后台操作
    2、RunWorkerAsync      开始执行后台操作
    3、ReportProgress      引发ProgressChanged事件  
    重要事件:
    1、DoWork              调用 RunWorkerAsync 时发生
    2、ProgressChanged     调用 ReportProgress 时发生
    3、RunWorkerCompleted  当后台操作已完成、被取消或引发异常时发生
    另外还有三个重要的参数是RunWorkerCompletedEventArgs以及DoWorkEventArgs、ProgressChangedEventArgs。
    BackgroundWorker的各属性、方法、事件的调用机制和顺序:

    从上图可见在整个生活周期内发生了3次重要的参数传递过程:
    参数传递1:此次的参数传递是将RunWorkerAsync(Object)中的Object传递到DoWork事件的DoWorkEventArgs.Argument,由于在这里只有一个参数可以传递,所以在实际应用往封装一个类,将整个实例化的类作为RunWorkerAsync的Object传递到DoWorkEventArgs.Argument;
    参数传递2:此次是将程序运行进度传递给ProgressChanged事件,实际使用中往往使用给方法和事件更新进度条或者日志信息;
    参数传递3:在DoWork事件结束之前,将后台线程产生的结果数据赋给DoWorkEventArgs.Result一边在RunWorkerCompleted事件中调用RunWorkerCompletedEventArgs.Result属性取得后台线程产生的结果。
    另外从上图可以看到DoWork事件是在后台线程中运行的,所以在该事件中不能够操作用户界面的内容,如果需要更新用户界面,可以使用ProgressChanged事件及RunWorkCompleted事件来实现。

   

 

我也再来补充下:上面3个函数,除了DoWork不能直接操作UI控件外(自己写委托可以或者设置check),其余的方法内都可以直接操作控件。

原创粉丝点击