事件驱动异步模式

事件驱动异步模式

 

前言

 

啥叫事件?啥叫驱动?异步又是啥玩意?这些字一个一个的我都认识,但是练起来我就不知道啥意思了,别急,往下看.

 

在下一篇文章中,我会专门介绍并发,同步,异步以及事件驱动变成的相关技术.

 

Event-based asynchronous(EAP)在多线程的环境中提供了一个简单的处理方式.

 

它有以下几个特性

 

1.支持取消

2.可以安全的更新WPFwindows Form空间

3.在completion event中可以查询异常信息.

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

5.同时执行多个操作,每个操作完成时都会接到通知.

6.等待资源变得可用,但不会停止(“挂起”)你得应用程序

7.使用熟悉的事件和委托模型与挂起的异步操作通信

 

EAP仅仅是一个模式而已,所以这些特性必须都由实现者来实现..net中有少数几个类支持这种模式,最著名的就是BackgroundWorkerSystem.Net.WebClient.

 

这个模式的本质是:每个类都提供了一些相似的成员来管理多线程,例如:

     

   public byte[] DownloadData(Uri address);
        public void DownloadDataAsync(Uri address);
        public void DownloadDataAsync(Uri address, object userToken);
        public event DownloadDataCompletedEventHandler DownloadDataCompleted;
 
        public void CancelAsync(); //取消操作
        public bool IsBusy { get; } //获取是否正在运行的信息。

 

下面是使用WebClient的例子:

    class Program
    {
        static void Main(string[] argss)
        {
            var wc = new WebClient();
            wc.DownloadStringCompleted += (sender, args) =>
                {
                    if (args.Cancelled)
                    {
                        Console.WriteLine("Canceled");
                    }
                    else if (args.Error != null)
                    {
                        Console.WriteLine("Exception:" + args.Error.Message);
                    }
                    else
                    {
                        Console.WriteLine(args.Result.Length + " chars were downloaded");
                    }
 
                };
            wc.DownloadStringAsync(new Uri("http://www.cnblogs.com/LoveJenny/"));
 
            Console.ReadLine();
        }
 
 
    }
 


分析:虽然一个WebClient有多个异步方法,但是因为他们都共享了相同的CancelAsycIsBusy属性,所以一次只能有一个异步操作.

 

 

 

BackgroundWorker

 

BackgroundWorkerSystem.ComponentModel下面的一个管理工作线程的帮助类,提供了下面几个特性.

 

1.支持取消

2.可以安全的更新WPFwindows Forms控件

3.在completion event中可以查询异常信息.

4.可以报告进度

5.因为实现了IComponent接口,所以可以被设计器使用.

6.BackgroundWorker使用了线程池,这意味着你永远都不能在一个BackgroundWorker线程上调用Abort方法.

 

    class Program
    {
        static BackgroundWorker _bw = new BackgroundWorker();
        public static void MainThread()
        {
            _bw.DoWork += new DoWorkEventHandler(_bw_DoWork);
            _bw.RunWorkerAsync("Message to worker");
            Console.ReadLine();
        }
        static void _bw_DoWork(object sender, DoWorkEventArgs e)
        {
            Console.WriteLine(e.Argument);
            //做一些耗时的事情
            for (int i = 0; i < 100000; i++)
            {
                Console.WriteLine(i);
            }
        }
        static void Main(string[] argss)
        {
            MainThread();
            Console.ReadLine();
        }
 
 
    }
 


下面的案例实现了进度报告

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace 事件异步
{
    class Program
    {
        static void Main(string[] args)
        {
            ThreadBackgroundWorker.MainThread();
            Console.ReadLine();
        }
    }
    class ThreadBackgroundWorker
    {
        static BackgroundWorker _bw;
        public static void MainThread()
        {
            _bw = new BackgroundWorker
            {
                WorkerReportsProgress=true,//允许报告进度
                WorkerSupportsCancellation =true//允许取消
            };
 
            _bw.DoWork += new DoWorkEventHandler(_bw_DoWork);
            _bw.ProgressChanged += new ProgressChangedEventHandler(_bw_ProgressChanged);
            _bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bw_RunWorkerCompleted);
            _bw.RunWorkerAsync("hello to worker");
            Console.WriteLine("Press Enter in the next 5 seconds to cancel.");
            Console.ReadLine();
 
            if (_bw.IsBusy)
            {
                _bw.CancelAsync();
            }
            Console.ReadLine();
        }
        static void _bw_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)//是否取消
            {
                Console.WriteLine("you canceled!");
            }
            else if (e.Error!=null)
            {
                Console.WriteLine("worker exception"+e.Error.ToString());
            }
            else
            {
                Console.WriteLine("Completed"+e.Result);
            }
        }
 
        static void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            //输出进度报告
 
            Console.WriteLine("Reacher"+e.ProgressPercentage+"%");
        }
 
        static void _bw_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <=100; i+=20)
            {
                if (_bw.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                _bw.ReportProgress(i);//报告进度
 
                Thread.Sleep(1000);
 
            }
            e.Result = 123;
        }
    }
}
 


分析:虽然我不知道这是个什么玩意,想干嘛,但是看着输出感觉老酷了,好炫,如果用到其他地方,比如你在家在一个网页的时候,提示你加载情况,你在下片的时候提示你下了多少,如果用的好感觉很酷,本屌才疏学浅没啥学问,不知道如何应用,等到以后慢慢来吧.

 

 

 

小小的结一下

 

说实话,这些东西已经超出我的个人理解范围了,已经不明白是个啥意思了,但是还是硬着头皮看完了,因为我觉得这就像我小时候老师让我背过三字经一样,那个时候我才上小学1年级,字都认不全,更别说理解三字经啥意思了,但是我当时背过了,随着年龄的增长,我就慢慢理解啥意思了,我相信做学问也差不多,现在因为我不会,不懂,就不学,那肯定将来还是不会!

你可能感兴趣的:(C#)