zoukankan      html  css  js  c++  java
  • C# 异步编程2 EAP 异步程序开发

    在前面一篇博文记录了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任务并行库正在快马加鞭赶来中...............

  • 相关阅读:
    win8应用商店安装路径
    GridView用存储过程实现分页
    Struts学习笔记之HTML标签库
    一个大学毕业生的反思
    JUnit in Action关于Controller的简明阐述
    Struts学习笔记之BEAN标签库
    Struts中web.xml和strutsconfig.xml配置详解
    Os学习笔记之处理机调度
    log4j.properties配置详解
    JUnit学习笔记之简介
  • 原文地址:https://www.cnblogs.com/dw039/p/7499852.html
Copyright © 2011-2022 走看看