zoukankan      html  css  js  c++  java
  • 什么是.Net的异步机制(委托Delegate) step 1

    什么是.Net异步机制呢?

     

    在解释这个话题前,我们先看看同步的程序,就是我们常用的Hello World 程序.

     

    Code 1:

    复制代码
     1    class Program
     2    {
     3        static void Main(string[] args)
     4        {
     5            // 查看当前的线程ID, 是否线程池里面的线程
     6            Console.WriteLine("1,Thread ID:#{0},Is PoolThread?{1}", 
    Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
     7
     8            AsyncTest test = new AsyncTest();
     9            string val = test.Hello("Andy Huang");
    10
    11            Console.WriteLine(val);
    12            Console.ReadLine(); // 让黑屏等待,不会直接关闭..
    13        }

    14    }

    15
    16    public class AsyncTest
    17    {
    18        public string Hello(string name)
    19        {
    20            // 查看当前的线程ID, 是否线程池里面的线程
    21            Console.WriteLine("2,Thread ID:#{0},Is PoolThread?{1}", 
    Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    22            return "Hello:" + name;
    23        }

    24    }
    复制代码

     

         

    1

    我们可以从图1看出,我们平常写的Hello 程序是同一个线程的,而且不是线程池理的线程程序.

        

    按照上面的程序稍做改动, 那么开始我们第一个异步的Hello World 程序.

     

    使用.Net 的委托机制来为我们的程序提供异步操作行为.

    1, 为我们的AsyncTest(Hello方法) 声明一个委托

    public delegate string AsyncEventHandler(string name);

    2,使用委托提供的BeginInvoke, EndInvoke 方法(具体使用下一篇文章详细介绍)来提供异步的调用.

    string val = test.Hello("Andy Huang");

    修改为

    AsyncEventHandler async = test.Hello;

        IAsyncResult result = async.BeginInvoke("Andy Huang", null, null);

        string val = async.EndInvoke(result);

     

    下面是完整的代码.

    Code 2:

    复制代码
     1    class Program
     2    {
     3        static void Main(string[] args)
     4        {
     5            // 查看当前的线程ID, 是否线程池里面的线程
     6            Console.WriteLine("1,Thread ID:#{0},Is PoolThread?{1}", 
    Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
     7
     8            AsyncTest test = new AsyncTest(); 
     9            //把Hello 方法分配给委托对象
    10            AsyncEventHandler async = test.Hello; //注释1,建议用=,不用+=
    11
    12            //发起一个异步调用的方法,赋值"Andy Huang", 返回IAsyncResult 对象
    13            IAsyncResult result = async.BeginInvoke("Andy Huang"nullnull);
    14
    15            //这里会阻碍线程,直到方法执行完毕
    16            string val = async.EndInvoke(result);
    17
    18            Console.WriteLine(val);
    19            Console.ReadLine(); // 让黑屏等待,不会直接关闭..
    20        }

    21    }

    22
    23    //我们使用委托来提供.Net的异步机制
    24    public delegate string AsyncEventHandler(string name);
    25    public class AsyncTest
    26    {
    27        public string Hello(string name)
    28        {
    29            // 查看当前的线程ID, 是否线程池里面的线程
    30            Console.WriteLine("2,Thread ID:#{0},Is PoolThread?{1}", 
    Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.IsThreadPoolThread);
    31            return "Hello:" + name;
    32        }

    33    }
    复制代码

     

     

           注释1: =操作符在于分配委托对象时候不需要初始化;并且异步调用时候只能有一个目标方法.

     

    2

     

    对比图1 和图2, ,可以看出(2,Thread ID:#10,Is PoolThread?True),在使用异步机制的时候,其实就是开启一个新的线程来执行我们的方法,并且这个线程来自 线程堆. 到这里,我们就很好的解释了什么是.Net异步机制?”

     

    说到这里,结束了吗? 可能大家会想其实使用异步就是多了个委托( public delegate string AsyncEventHandler(string name);) 那么到底为我们做了些什么呢?

     

    通过反编译(微软提供的IL Disassembler)我们看到


    3

     

    编译器为我们生成了下面类定义(其实委托就是一个类)

     

    Code 3

    public sealed class AsyncEventHandler : MulticastDelegate

        {

            public AsyncEventHandler(object @object, IntPtr method)

            {....}

            public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object)

            {...}

            public virtual string EndInvoke(IAsyncResult result)

            {...}

            public virtual string Invoke(string name)

            {...}

        }

     

    继承于MulticastDelegate, 提供了BeginInvoke / EndInvoke / Invoke.

    Invoke 是我们Code 1 同步调用的方法,当然我们也可以直接使用Invoke来同步调用.

    BeginInvoke / EndInvoke Code 2中使用的异步调用的方法,下篇文章我会详细介绍

     

    什么时候使用.Net异步机制呢

     

    异步操作通常用于执行完成时间可能较长的任务,如打开大文件、连接远程计算机或查询数据库。异步操作在主应用程序线程以外的线程中执行。应用程序调用方法异步执行某个操作时,应用程序仍然可以继续执行当前的程序。

     

    .NET Framework 的许多方面都支持异步编程功能,这些方面包括:

    ·         文件(File) IO、流(Stream) IO、套接字(Socket) IO。

    ·         网络。

    ·         远程处理信道(HTTP、TCP)和代理。

    ·         使用 ASP.NET 创建的 XML Web services。

    ·         ASP.NET Web 窗体。

    ·         使用 MessageQueue 类的消息队列。

     

     

    以上有word 文档直接粘贴,排版可能不太看,你可以通过下面来下载相应的代码/文档

    1, 代码

    2,原始文档(doc) 

  • 相关阅读:
    C++ 将对象写入文件 并读取
    IronPython fail to add reference to WebDriver.dll
    How to Capture and Decrypt Lync Server 2010 TLS Traffic Using Microsoft Tools
    .net code injection
    数学系学生应该知道的十个学术网站
    Difference Between Currency Swap and FX Swap
    Swift开源parser
    谈谈我对证券公司一些部门的理解(前、中、后台)[z]
    JDK8记FullGC时候Metaspace内存不会被垃圾回收
    JVM源码分析之JDK8下的僵尸(无法回收)类加载器[z]
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/3105391.html
Copyright © 2011-2022 走看看