step3-异步编程模式(C#篇)

Posted 全栈工程师成长记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了step3-异步编程模式(C#篇)相关的知识,希望对你有一定的参考价值。

      不要问我为什么总发C#方向的技术总结。没有办法,笔者从事工作一直是C#方向。C#语言有着独特的优美与简洁。俗话说,存在即合理。我想这也是C#这些年在中国市场有着自己市场的原因。  

      另外,我看了java的异步编程,跟C#其实思想都差不多。都了解下,不是什么坏事。那是咋说来着,知己知彼......废话不多说,讲正题吧。



01


异步编程概述


1.异步编程模式使用场景及优点

使用场景:同时执行多项任务、但仍能响应用户交互的应用程序。

使用类:BackgroundWorker

优点:

(1)“在后台”执行耗时任务(例如下载和数据库操作),但不会中断您的应用程序。

(2)同时执行多个操作,每个操作完成时都会接到通知。

(3)等待资源变得可用,但不会停止(“挂起”)您的应用程序。

(4)使用熟悉的事件和委托模型与挂起的异步操作通信。





02



调用机制


(1)重要事件:


DoWork:具体的线程执行的代码块,就是让这个线程做什么的,自己填充内容。。

ProgressChanged:用于更新进度的回调,比如有一个进度条,当doWork中执行了任务的时候,调用BackgroundWork的ReportProgress方法,就可以把进度报告出来,然后这个函数捕获报告的内容,进行具体的进度操作。使用该函数的话,必须将BackgroundWork的WorkerReportsProgress属性设置为true。

RunWorkerCompleted:当线程执行完内容的回调函数。

另外还有三个重要的参数是RunWorkerCompletedEventArgs以及DoWorkEventArgs、ProgressChangedEventArgs。


(2)重要属性:


CancellationPending:获取一个值,指示应用程序是否已请求取消后台操作。通过在DoWork事件中判断CancellationPending属性可以认定是否需要取消后台操作(也就是结束线程);

IsBusy:获取一个值,指示 BackgroundWorker 是否正在运行异步操作。

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

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


(3)重要方法:


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

RunWorkerAsync:开始执行后台操作。

ReportProgress:引发ProgressChanged事件。


(4)调用机制和顺序:


参数传递1:此次的参数传递是将RunWorkerAsync(Object)中的Object传递到DoWork事件的DoWorkEventArgs.Argument,由于在这里只有一个参数可以传递,所以在实际应用往封装一个类,将整个实例化的类作为RunWorkerAsync的Object传递到DoWorkEventArgs.Argument;

参数传递2:此次是将程序运行进度传递给ProgressChanged事件,实际使用中往往使用给方法和事件更新进度条或者日志信息;

参数传递3:在DoWork事件结束之前,将后台线程产生的结果数据赋给DoWorkEventArgs.Result一边在RunWorkerCompleted事件中调用RunWorkerCompletedEventArgs.Result属性取得后台线程产生的结果。

另外从上图可以看到DoWork事件是在后台线程中运行的,所以在该事件中不能够操作用户界面的内容,如果需要更新用户界面,可以使用ProgressChanged事件及RunWorkCompleted事件来实现。


step3-异步编程模式(C#篇)





03



一言不合上Demo


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();

        }

    }

}

                               

step3-异步编程模式(C#篇)step3-异步编程模式(C#篇)          结束          

以上是关于step3-异步编程模式(C#篇)的主要内容,如果未能解决你的问题,请参考以下文章

C# :异步编程的注意点

C#如何使用异步编程

[C#] 异步编程 - 剖析异步方法

C#如何使用异步编程BeginInvoke/EndInvoke

C#并发编程之异步编程(线程讨论)

[C#] 走进异步编程的世界 - 剖析异步方法(下)