在前面一篇博文记录了C# APM异步编程的知识,今天再来分享一下EAP(基于事件的异步编程模式)异步编程的知识。后面会继续奉上TPL任务并行库的知识,喜欢的朋友请持续关注哦。
EAP异步编程算是C#对APM的一种补充,让异步编程拥有了一系列状态事件。如果你看过本系列的前一篇文章《C# 异步编程1 APM 异步程序开发》,并假设你是微软C#语言开发组的一员,现在让你来设计基于事件的异步编程模式。那你是会利用之前的APM进行改造?还是进行再次创造呢?所以当你对相关dll进行反编译,会惊喜的发现EAP实际上是对APM增加了事件event后的封装。因此这篇博文的篇幅不会很长,我们只介绍EAP模式的基本信息和编程实现。对于事件 event 我后续增加博文阐述其功能及用法。
EAP 基于事件的异步编程模式
当我们使用EAP模式进行异步编程时,需要满足以下2个条件:
1、要进行异步的方法其方法名应该以XXXAsync结尾
2、要有一个名为XXXCompleted的事件监听异步方法的完成
3、可增加一个CancelAsync方法用于取消正在执行的异步方法(可选)
示例代码:
/// <summary> /// EAP是对APM的封装 /// </summary> public class Worker { public enum WorkerStatus { Cancel = 0,Running=1, Completed=2 } public class WorkerEventArgs :EventArgs { public WorkerStatus Status { get; set; } public string Message { get; set; } } public Worker() { } public event EventHandler<WorkerEventArgs> OnWorkCompleted; IAsyncResult asyncResult = null; Thread thread = null; public void WorkAsync() { Worker _this = this; Action action = () => { thread = Thread.CurrentThread; Thread.Sleep(10000); Console.WriteLine(string.Format("线程:{0},Work Over.", Thread.CurrentThread.ManagedThreadId)); }; asyncResult = action.BeginInvoke((result) => { WorkerEventArgs e = null; try { action.EndInvoke(asyncResult); } catch (ThreadAbortException ex) { e = new WorkerEventArgs() { Status = WorkerStatus.Cancel, Message = "异步操作被取消" }; } if (null != _this.OnWorkCompleted) { _this.OnWorkCompleted.Invoke(this, e); } }, this); } public void CancelAsync() { if (null != thread) thread.Abort(); } }
调用程序使用WinForm来进行,示例代码如下(仅为演示用):
Worker worker; private void Btn_Start_Click(object sender, EventArgs e) { worker = new Worker(); worker.OnWorkCompleted += WorkOver; worker.WorkAsync(); Console.WriteLine(string.Format("线程:{0}", Thread.CurrentThread.ManagedThreadId)); } private void Btn_Cancel_Click(object sender, EventArgs e) { worker.CancelAsync(); } private void WorkOver(object sender, Worker.WorkerEventArgs e) { if (null != e) { if (Worker.WorkerStatus.Cancel == e.Status) { MessageBox.Show(e.Message); } } else { Console.WriteLine(string.Format("线程:{0},委托回调完成.", Thread.CurrentThread.ManagedThreadId)); } }
效果展示:
DBA08BF0362B.png" alt="">
注意事项(重要):
1、APM异步编程时,因异步代码执行在单独的线程中,异步代码中出现的异常应该在调用EndXXX时捕获。
2、EAP异步编程时,因上述同样原因,代码中的异常信息会被传递到Completed事件的EventArgs参数中。
EAP(基于事件的异步编程模式)核心内容并不多,并且如网路、IO等耗时类 Ms 已添加了EAP相关异步功能,我们直接拿来用就好。尤其是后续TPL并行任务的加入,用户自定义EAP异步功能的机会更是了了,但EAP中相关的知识点如线程、委托、事件等仍然是重要的.......................
TPL任务并行库正在快马加鞭赶来中...............