基于事件的异步模式——01.backgroundWorker

以下内容仅作为学习提高记录,有错误恳请批评。
引用:1.C#高级编程第七版。

   2.http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(v=vs.110).aspx

1.前言

在windows窗体和WPF等控件绑定到一个线程上,这时,对于每个控件,只能从创建控件的主线程中调用方法,而对于一个后台线程,就无法从主线程中访问UI控件。

对于这种可以通过异步模式实现。即创建他的线程之外的线程调用Invoke(),BeginInvoke(),EndInvoke()方法和InvokeRequried属性等异步版本。

同时可以解决界面假死现象。

2.BackgroundWorker类

BackgroundWorker类是异步事件模式的一种实现方案。

  属性(摘录部分):

  CancellationPending  获取一个值,指示应用程序是否已请求取消后台操作。

  WorkerReportsProgress 获取或设置一个值,该值指示 BackgroundWorker 能否报告进度更新。

  WorkerSupportsCancellation 获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。

  方法(摘录部分):

  CancelAsync  请求取消挂起的后台操作

  OnDoWork   引发DoWork事件

  OnProgressChanged  引发 ProgressChanged 事件。

  OnRunWorkerCompleted  引发 RunWorkerCompleted 事件。

  ReportProgress   引发 ProgressChanged 事件。

  RunWorkerAsync()  开始执行后台操作。

  事件(摘录部分):

  DoWork  调用 RunWorkerAsync 时发生。

  ProgressChanged  调用 ReportProgress 时发生。

  RunWorkerCompleted  当后台操作已完成、被取消或引发异常时发生

3.DEMO

  若要为后台操作做好准备,请添加 DoWork 事件的事件处理程序。 在此事件处理程序中调用耗时的操作。 若要开始此操作,请调用 RunWorkerAsync。 若要收到进度更新的通知,请处理 ProgressChanged 事件。 若要在操作完成时收到通知,请处理 RunWorkerCompleted 事件。

namespace _11._1_BackgroundWorker
{
    /// <summary>
    /// 基于事件的异步模式
    /// 开始事件:DoWork+=
    /// 完成时间事件:RunWorkerCompleted+=
    /// 取消功能:把WorkerSupportCancellation属性设置为true就支持取消功能。也可以通过CancelAsync()方法来取消。
    /// 验证是否取消工作:CancellationPending属性
    /// 进度信息:WorkerReportProgess属性指定正在进行的任务是否返回进度信息。如果返回,可指定ProgessChanged事件来接受进度信息。完成调用ReportProgess()
    /// 好处:可以切换到主调线程上,参数在线程之间相互调用。同时解决窗体假死现象
    /// </summary>
    public partial class Form1 :Form
    {
        private BackgroundWorker backgroundWorker;//
        public Form1()
        {
            InitializeComponent();
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerSupportsCancellation = true;//取消功能:必须把设置为True;
            backgroundWorker.WorkerReportsProgress = true;//
            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);//开始异步操作结果
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);//进度信息
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);//完成异步操作结果
        }

        void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
                this.txtResult.Text = "Cancelled";
            else
                this.txtResult.Text = e.Result.ToString();
        }


        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var t = e.Argument as Tuple<int, int>;
            for (int i = 0; i <= 10; i++)
            {
                System.Threading.Thread.Sleep(500);
                backgroundWorker.ReportProgress(i * 10);
                if (backgroundWorker.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
            }
            e.Result = t.Item1 + t.Item2;//设置异步操作的结果。
        }

        private void button1_Click(object sender, EventArgs e)
        {            
            if(!string.IsNullOrEmpty(txtX.Text))
                   backgroundWorker.RunWorkerAsync(Tuple.Create<int,int>(int.Parse(txtX.Text), int.Parse(txtY.Text)));//启动BackgroundWorker控件,并传递参数(x,y)

        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            this.txtX.Text = e.X.ToString();
            this.txtY.Text = e.Y.ToString();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            backgroundWorker.CancelAsync();
        }

    }
}

  

 

原文地址:https://www.cnblogs.com/w519/p/3904199.html