事件驱动异步模式
啥叫事件?啥叫驱动?异步又是啥玩意?这些字一个一个的我都认识,但是练起来我就不知道啥意思了,别急,往下看.
在下一篇文章中,我会专门介绍并发,同步,异步以及事件驱动变成的相关技术.
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是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年级,字都认不全,更别说理解三字经啥意思了,但是我当时背过了,随着年龄的增长,我就慢慢理解啥意思了,我相信做学问也差不多,现在因为我不会,不懂,就不学,那肯定将来还是不会!