事件驱动异步模式

事件驱动异步模式

前言

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

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

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

它有以下几个特性

1.支持取消

2.可以安全的更新WPF或windows Form空间

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

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

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

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

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

 

EAP仅仅是一个模式而已,所以这些特性必须都由实现者来实现.在.net中有少数几个类支持这种模式,最著名的就是BackgroundWorker和System.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有多个异步方法,但是因为他们都共享了相同的CancelAsyc和IsBusy属性,所以一次只能有一个异步操作.

BackgroundWorker

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

 

1.支持取消

2.可以安全的更新WPF或windows 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年级,字都认不全,更别说理解三字经啥意思了,但是我当时背过了,随着年龄的增长,我就慢慢理解啥意思了,我相信做学问也差不多,现在因为我不会,不懂,就不学,那肯定将来还是不会!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-05 04:58:40

事件驱动异步模式的相关文章

前端基本知识(四):JS的异步模式:1、回调函数;2、事件监听;3、观察者模式;4、promise对象

JavaScript语言将任务的执行模式可以分成两种:同步(Synchronous)和异步(Asychronous). “同步模式”就是一个任务完成之后,后边跟着一个任务接着执行:程序的执行顺序和排列顺序是一直的:”异步模式”则完全不同,每一个任务都有一个或者多个回调函数(callback),前一个任务结束的时候,不是执行下一个任务,二十执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务顺序不一致的,异步的. 在浏览器端,耗时时间长的操作都应该异步执行,避免浏览器数去

实现基于Task的异步模式

返回该系列目录<基于Task的异步模式--全面介绍> 生成方法 编译器生成 在.NET Framework 4.5中,C#编译器实现了TAP.任何标有async关键字的方法都是异步方法,编译器会使用TAP执行必要的转换从而异步地实现方法.这样的方法应该返回Task或者Task<TResult>类型.在后者的案例中,方法体应该返回一个TResult,且编译器将确保通过返回的Task<TResult>是可利用的.相似地,方法体内未经处理的异常会被封送到输出的task,造成返

MSDN搬运 之 [基于事件的异步模式]

基于事件的异步模式概述 那些同时执行多项任务.但仍能响应用户交互的应用程序通常需要实施一种使用多线程的设计方案.System.Threading 命名空间提供了创建高性能多线程应用程序所必需的所有工具,但要想有效地使用这些工具,需要有丰富的使用多线程软件工程的经验.对于相对简单的多线程应用程序,BackgroundWorker 组件提供了一个简单的解决方案.对于更复杂的异步应用程序,请考虑实现一个符合基于事件的异步模式的类. 基于事件的异步模式具有多线程应用程序的优点,同时隐匿了多线程设计中固有

.Net中的几种异步模式

.Net中的几种异步模式 .Net中的几种异步模式基于事件的异步模式(EAP)IAsyncResult接口简单的异步模式--引入lambdaTask手动异步编程的问题 在C# 5.0引入async之前,存在几种异步编程模式,比如Event-based Asynchronous Pattern.IAsyncResult接口.Task等等. 基于事件的异步模式(EAP) private void DumpWebPage(Uri uri) { WebClient webClient = new Web

Task的异步模式

Task的异步模式 返回该系列目录<基于Task的异步模式--全面介绍> 生成方法 编译器生成 在.NET Framework 4.5中,C#编译器实现了TAP.任何标有async关键字的方法都是异步方法,编译器会使用TAP执行必要的转换从而异步地实现方法.这样的方法应该返回Task或者Task<TResult>类型.在后者的案例中,方法体应该返回一个TResult,且编译器将确保通过返回的Task<TResult>是可利用的.相似地,方法体内未经处理的异常会被封送到输

Spring MVC的异步模式

高性能的关键:Spring MVC的异步模式 我承认有些标题党了,不过话说这样其实也没错,关于“异步”处理的文章已经不少,代码例子也能找到很多,但我还是打算发表这篇我写了好长一段时间,却一直没发表的文章,以一个更简单的视角,把异步模式讲清楚. 什么是异步模式 要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式: (图1) 浏览器发起请求,Web服务器开一个线程处理,处理完把处理结果返回浏览器.好像没什么好说的了,绝大多数Web服务器都如此般处理.现在想想如果处理的过程中需要调用

与其他.Net异步模式和类型进行互操作

返回该系列目录<基于Task的异步模式--全面介绍> Tasks和异步编程模型APM(Tasks and the Asynchronous Programming Model) 从APM到Tasks APM模式依赖两个对应的方法来表示一个异步操作:BeginMethodName和EndMethodName.在高级别,begin方法接受的参数和相应的同步方法MethodName的参数是一样的,而且还接受一个AsyncCallback和一个object state.begin方法然后返回IAsyn

实践基于Task的异步模式

Await 返回该系列目录<基于Task的异步模式--全面介绍> 在API级别,实现没有阻塞的等待的方法是提供callback(回调函数).对于Tasks来说,这是通过像ContinueWith的方法实现的.基于语言的异步支持通过允许在正常控制流内部等待异步操作隐藏callbacks,具有和编译器生成的代码相同的API级别的支持. 在.Net 4.5,C#直接异步地支持等待的Task和Task<TResult>,在C#中使用"await"关键字.如果等待一个Ta

Spring MVC的异步模式DefferedResult

原文:http://www.importnew.com/21051.html 什么是异步模式 要知道什么是异步模式,就先要知道什么是同步模式,先看最典型的同步模式: (图1) 浏览器发起请求,Web服务器开一个线程处理,处理完把处理结果返回浏览器.好像没什么好说的了,绝大多数Web服务器都如此般处理.现在想想如果处理的过程中需要调用后端的一个业务逻辑服务器,会是怎样呢? (图2) 调就调吧,上图所示,请求处理线程会在Call了之后等待Return,自身处于阻塞状态.这也是绝大多数Web服务器的做