C# 异步编程2 EAP 异步程序开发

来源:互联网 发布:淘宝代销下单流程 编辑:程序博客网 时间:2024/05/21 18:12

在前面一篇博文记录了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));            }        }

效果展示:

注意事项(重要):

1、APM异步编程时,因异步代码执行在单独的线程中,异步代码中出现的异常应该在调用EndXXX时捕获。

2、EAP异步编程时,因上述同样原因,代码中的异常信息会被传递到Completed事件的EventArgs参数中。

EAP(基于事件的异步编程模式)核心内容并不多,并且如网路、IO等耗时类 Ms 已添加了EAP相关异步功能,我们直接拿来用就好。尤其是后续TPL并行任务的加入,用户自定义EAP异步功能的机会更是了了,但EAP中相关的知识点如线程、委托、事件等仍然是重要的.......................

TPL任务并行库正在快马加鞭赶来中...............