• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    .NET中基于事件的异步模式-EAP
    前言
    在C# 5.0中,新增了async await 2个关键字支持异步编程的操作。在讲述这两个关键字之前,我先总结一下.NET中的常见的异步编程模型。
    异步编程一直是比较复杂的问题,其中要处理多线程之间的数据同步、获取进度、可取消、获取结果、不影响主线程操作、多个任务之间互相不影响等,因此需要设计编程模型去处理此类问题。

    从.NET 4.5开始,支持的三种异步编程模式
    基于事件的异步编程设计模式 (EAP,Event-based Asynchronous Pattern)
    异步编程模型(APE,Asynchronous Programming Model)
    基于任务的编程模型(TAP,Task-based Asynchronous Pattern)
    目前新版的.NET是偏向于建议使用TAP方式进行异步编程,WINRT中的异步操作就只有TAP的身影,async await关键字也只是支持TAP的编程模型。

    基于事件的异步模式 - EAP
    EAP的编程模式的代码有以下特点:
    将有一个或多个名为 “[方法名称]Async” 的方法。这些方法可能会创建同步版本的镜像,这些同步版本会在当前线程上执行相同的操作。
    该类还可能有一个 “[方法名称]Completed” 事件,监听异步方法的结果。
    它可能会有一个 “[方法名称]AsyncCancel”(或只是 CancelAsync)方法,用于取消正在进行的异步操作。
    下面是一个符合此模式的类声明示例
    复制代码 代码如下:

    public class AsyncExample
    {
    // Synchronous methods.
    public int Method1(string param);
    public void Method2(double param);
    // Asynchronous methods.
    public void Method1Async(string param);
    public void Method1Async(string param, object userState);
    public event Method1CompletedEventHandler Method1Completed;
    public void Method2Async(double param);
    public void Method2Async(double param, object userState);
    public event Method2CompletedEventHandler Method2Completed;
    public void CancelAsync(object userState);
    public bool IsBusy { get; }
    // Class implementation not shown.
    }

    这里虚构的 AsyncExample 类有两个方法,都支持同步和异步调用。同步重载的行为类似于方法调用,它们对调用线程执行操作;如果操作很耗时,则调用的返回可能会有明显的延迟。异步重载将在另一个线程上启动操作,然后立即返回,允许在调用线程继续执行的同时让操作“在后台”执行。
    System.Net.WebClient 本身就有很多EAP的例子,以它的DownloadString为例,WebClient中跟DownloadString相关的方法有
    DownloadString:同步下载字符串资源的方法,此方法阻塞当前线程。
    DownloadStringAsync:使用EAP异步编程模式下载字符串资源的方法,此方法不会阻塞当前线程。
    DownloadStringCompleted:响应异步下载时完成的事件。
    DownloadProgressChanged:响应异步下载时进度变化。
    调用模型示例如下
    复制代码 代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    namespace AsyncTest1.EAP
    {
    public class EAPRunTest1
    {
    public static void AsyncRun() {
    Utility.Log("AsyncRun:start");
    //测试网址
    string url = "http://sports.163.com/nba/";
    using (WebClient webClient = new WebClient()) {
    //监控下载进度
    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
    //监控完成情况
    webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
    webClient.DownloadStringAsync(new Uri(url));
    Utility.Log("AsyncRun:download_start");
    }
    }
    static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
    string log = "AsyncRun:download_completed";
    log += "|cancel=" + e.Cancelled.ToString() ;
    if (e.Error != null)
    {
    //出现异常,就记录异常
    log += "|error=" + e.Error.Message;
    }
    else {
    //没有出现异常,则记录结果
    log += "|result_size=" + Utility.GetStrLen(e.Result);
    }
    Utility.Log(log);
    }
    static void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
    Utility.Log("AsyncRun:download_progress|percent=" + e.ProgressPercentage.ToString());
    }
    }
    }

    运行结果
    2012-12-28 00:39:39:621 AsyncRun:start
    2012-12-28 00:39:40:377 AsyncRun:download_start
    2012-12-28 00:39:40:903 AsyncRun:download_progress|percent=1
    2012-12-28 00:39:40:933 AsyncRun:download_progress|percent=3
    2012-12-28 00:39:40:933 AsyncRun:download_progress|percent=5
    2012-12-28 00:39:40:934 AsyncRun:download_progress|percent=5
    2012-12-28 00:39:40:975 AsyncRun:download_progress|percent=9
    2012-12-28 00:39:41:068 AsyncRun:download_progress|percent=21
    2012-12-28 00:39:41:131 AsyncRun:download_progress|percent=29
    2012-12-28 00:39:41:182 AsyncRun:download_progress|percent=37
    2012-12-28 00:39:41:298 AsyncRun:download_progress|percent=50
    2012-12-28 00:39:41:354 AsyncRun:download_progress|percent=58
    2012-12-28 00:39:41:447 AsyncRun:download_progress|percent=74
    2012-12-28 00:39:41:489 AsyncRun:download_progress|percent=82
    2012-12-28 00:39:41:582 AsyncRun:download_progress|percent=100
    2012-12-28 00:39:41:582 AsyncRun:download_progress|percent=100
    2012-12-28 00:39:41:614 AsyncRun:download_completed|cancel=False|result_size=205568
    您可能感兴趣的文章:
    • asp.net在事件中启动线程来打开一个页面的实现方法
    • asp.net页面触发事件panel滚动条高度不变的实现方法
    • ASP.NET中实现定制自己的委托和事件参数类
    • .NET WinFrom中给文本框添加拖放事件的代码
    • .net自定义事件示例分享
    • 详解ASP.NET页面生命周期事件
    • ASP.NET 页面事件执行顺序介绍
    • .NET图像界面按钮的clicked事件浅谈
    • .net,js捕捉文本框回车键事件的小例子(兼容多浏览器)
    • .Net WInform开发笔记(五)关于事件Event
    • .NET事件监听机制的局限与扩展分析
    上一篇:js获取Treeview选中的节点(C#选中CheckBox项)
    下一篇:TrieTree服务-组件构成及其作用介绍
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    .NET中基于事件的异步模式-EAP .NET,中,基于,事件,的,异步,