什么是.net的异步机制呢?

解释这个话题之前,先让我们来看看同步执行的程序

https://github.com/chucklu/Test/blob/master/DotNet4.5开发指南/并行处理和并发/异步编程模式/APM/SyncProcedure/Program.cs

  1. static class SyncTest
  2. {
  3. public static void Method()
  4. {
  5.  
  6. Console.WriteLine("SyncTest类中的Method()函数的线程ID是{0}", Thread.CurrentThread.ManagedThreadId);//Environment.CurrentManagedThreadId
  7. if (Thread.CurrentThread.IsThreadPoolThread)//判断当前线程是否托管在线程池上
  8. {
  9. Console.WriteLine("SyncTest类中的Method()函数的线程托管于线程池");
  10. }
  11. else
  12. {
  13. Console.WriteLine("SyncTest类中的Method()函数的线程没有托管在线程池上");
  14. }
  15. }
  16. }
  17.  
  18. class Program
  19. {
  20. static void Main(string[] args)
  21. {
  22. Console.WriteLine("Program类中的Main()函数的线程ID是{0}", Thread.CurrentThread.ManagedThreadId);//Environment.CurrentManagedThreadId
  23. if (Thread.CurrentThread.IsThreadPoolThread)//判断当前线程是否托管在线程池上
  24. {
  25. Console.WriteLine("Program类中的Main()函数的线程托管于线程池");
  26. }
  27. else
  28. {
  29. Console.WriteLine("Program类中的Main()函数的线程没有托管在线程池上");
  30. }
  31. Console.WriteLine();
  32.  
  33. SyncTest.Method();//调用静态类的静态方法
  34.  
  35. Console.Read();//阻塞,确保能看到上面的打印信息
  36. }
  37. }

执行结果如下图所示

从图中可以看出,在主函数中调用另外一个类SyncTest的方法,

进入方法Method的时候,此方法还是和Main函数在同一个线程上执行的

并且该线程不是托管在线程池上的线程

接下来写一个通过委托,进行异步执行的方法

https://github.com/chucklu/Test/blob/master/DotNet4.5开发指南/并行处理和并发/异步编程模式/APM/AsyncProcedure/Program.cs

不要尝试去查看BeginInvoke和EndInvoke的实现,右键,转到定义,是看不到的。这两个方法是CLR为委托类型添加的

  1. /// <summary>
  2. /// 声明一个委托 委托的名字是AsyncHandler
  3. /// </summary>
  4. /// <param name="name"></param>
  5. public delegate void AsyncHandler();//委托的声明方式类似于函数,只是比函数多了一个delegate关键字
  6.  
  7. static class AsyncTest
  8. {
  9. public static void Method()
  10. {
  11. Console.WriteLine("AsyncTest类中的Method()函数的线程ID是{0}", Thread.CurrentThread.ManagedThreadId);//Environment.CurrentManagedThreadId
  12. if (Thread.CurrentThread.IsThreadPoolThread)//判断当前线程是否托管在线程池上
  13. {
  14. Console.WriteLine("AsyncTest类中的Method()函数的线程托管于线程池");
  15. }
  16. else
  17. {
  18. Console.WriteLine("AsyncTest类中的Method()函数的线程没有托管在线程池上");
  19. }
  20. }
  21. }
  22.  
  23. class Program
  24. {
  25. static void Main(string[] args)
  26. {
  27. Console.WriteLine("Program类中的Main()函数的线程ID是{0}", Thread.CurrentThread.ManagedThreadId);//Environment.CurrentManagedThreadId
  28. if (Thread.CurrentThread.IsThreadPoolThread)//判断当前线程是否托管在线程池上
  29. {
  30. Console.WriteLine("Program类中的Main()函数的线程托管于线程池");
  31. }
  32. else
  33. {
  34. Console.WriteLine("Program类中的Main()函数的线程没有托管在线程池上");
  35. }
  36. Console.WriteLine();
  37.  
  38. //把Method 方法分配给委托对象
  39. AsyncHandler async = AsyncTest.Method; //
  40.  
  41. //发起一个异步调用的方法,返回IAsyncResult 对象
  42. IAsyncResult result = async.BeginInvoke(null,null);
  43.  
  44. //这里会阻碍线程,直到方法执行完毕
  45. async.EndInvoke(result);
  46.  
  47. Console.Read();
  48. }
  49. }

运行结果如下图所示

从上图可以看出,委托的BeginInvoke,是新开了一个线程运行方法,并且该线程是托管在线程池上的

上面两个代码的示例,区别在于,第二个使用的是委托的BeginInvoke方法

通过反编译工具,我们可以查看委托具体做了什么,一般.net Reflector不错,最近新发现一个叫ILSpy的,开源的反编译工具

https://github.com/icsharpcode/ILSpy   官网的.sln是VS2013的,如果不想自己编译的,也可以去官网下载编译好的exe程序

官网链接是http://ilspy.net/     右上角有一个Download Binaries,点击下载就可以了

接下来上图,反编译的结果

从上图可以发现AsyncHandler委托的结构如下

  1. public extern AsyncHandler(object @object, IntPtr method);
  2. public virtual extern IAsyncResult BeginInvoke(AsyncCallback callback, object @object);
  3. public virtual extern void EndInvoke(IAsyncResult result);
  4. public virtual extern void Invoke();

而且可以发现继承层次,AsyncHandler从MulticastDelegate继承,再上层是Delegate类(注意,大写的Delegate表示的是类,而不是delegate关键字)

去msdn上找了相关信息

Delegate类

  1. public abstract class Delegate : ICloneable,ISerializable
  2.  
  3. The Delegate class is the base class for delegate types.
  4. Delegate类是delegate类型的基类
  5. However, only the system and compilers can derive explicitly from the Delegate class or from the MulticastDelegate class.
  6. 然后只有系统和编译器才可以从Delegate类或者MulticastDelegate类进行派生
  7. It is also not permissible to derive a new type from a delegate type.
  8. 从委托类型派生一个新类型也是不允许的
  9. The Delegate class is not considered a delegate type; it is a class used to derive delegate types.
  10. Delegate类并不是委托类型,它只是一个用于派生委托类型的类。
  11. Most languages implement a delegate keyword, and compilers for those languages are able to derive from the MulticastDelegate class; therefore, users should use the delegate keyword provided by the language.
  12. 大多数语言实现了delegate关键字,并且这些语言的编译器是能够从MulticastDelegate类进行派生的,所以,开发者们应该使用开发语言所提供的delegate关键字
  13.  
  14. The common language runtime provides an Invoke method for each delegate type, with the same signature as the delegate.
  15. CLR为每一个委托类型提供了一个Invoke方法,并且该方法和delegate拥有相同的签名
  16.  
  17. The common language runtime provides each delegate type with BeginInvoke and EndInvoke methods, to enable asynchronous invocation of the delegate.
  18. CLR为每一个委托类型提供了BeginInvokeEndInvoke方法,来确保委托的异步调用

  1. MulticastDelegate
  1. public abstract class MulticastDelegate : Delegate
  2.  
  3. MulticastDelegate is a special class. Compilers and other tools can derive from this class, but you cannot derive from it explicitly. The same is true of the Delegate class.
  4. 多播委托是一个特殊的类。编译器或者其他工具,可以从从这个类派生,但是你不能显式地从这个类派生。同样的规则适用于Delegate类。
  5.  
  6. In addition to the methods that delegate types inherit from MulticastDelegate, the common language runtime provides two special methods: BeginInvoke and EndInvoke.
  7. delegate关键字声明的委托,不但继承了多播委托的方法,并且CLR还提供了两个特殊的方法BeginInvokeEndInvoke

  1. 更多关于BeginInvokeEndInvoke的信息可以参见此链接[使用异步方式调用同步方法]http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.110).aspx

使用委托进行异步编程http://msdn.microsoft.com/zh-cn/library/22t547yb(v=vs.110).aspx

转载自http://www.cnblogs.com/AndyHuang/archive/2008/12/24/1361267.html   (有自己的修改和理解)

通过委托来实现异步 Delegate的BeginInvoke和EndInvoke的更多相关文章

  1. 用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

    让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法.定义与您需要调用的方法具有相同签名的委托:公共语言运行库将自动为该委托定义具有适当签名的Begin ...

  2. 【C#】用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

    让我们首先了解下什么时候用到C#异步调用: .NET Framework 允许您C#异步调用任何方法.定义与您需要调用的方法具有相同签名的委托:公共语言运行库将自动为该委托定义具有适当签名的Begin ...

  3. delegate 中的BeginInvoke和EndInvoke方法

    开发语言:C#3.0 IDE:Visual Studio 2008 一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能 ...

  4. 读书笔记 C#委托的BeginInvoke、EndInvoke之浅析

    c#中有一种类型叫委托,它是一种引用类型.可以引用静态与非静态的方法,且这些方法的参数列表和返回值类型必须与所声明的委托一致. 委托引用的方法可以通过BeginInvoke和EndInvoke来异步进 ...

  5. C#--委托的同步,异步,回调函数

    原文地址 同步调用 委托的Invoke方法用来进行同步调用.同步调用也可以叫阻塞调用,它将阻塞当前线程,然后执行调用,调用完毕后再继续向下进行. using System; using System. ...

  6. c#委托中的同步和异步方法即BeginInvoke和EndInvoke

    学习多线程之前我们先了解一下电脑的一些概念,比如进程,线程,这个参考https://www.cnblogs.com/loverwangshan/p/10409755.html 这篇文章.今天我们接着来 ...

  7. C#线程系列讲座(1):BeginInvoke和EndInvoke方法

    一.C#线程概述 在操作系统中一个进程至少要包含一个线程,然后,在某些时候需要在同一个进程中同时执行多项任务,或是为了提供程序的性能,将要执行的任务分解成多个子任务执行.这就需要在同一个进程中开启多个 ...

  8. C#线程应用实例(part1) 之 BeginInvoke和EndInvoke

    最近这个公司是做 winfrom 开发的 , 这段时间就好好的学学WCF , 公司框架什么的自己去琢磨! 这里主要写一些 winfrom 中 用到的一些陌生 技术 1.BeginInvoke  以前B ...

  9. 转:C#线程系列讲座(1) BeginInvoke和EndInvoke方法

    转载自:http://www.cnblogs.com/levin9/articles/2319248.html 开发语言:C#3.0IDE:Visual Studio 2008本系列教程主要包括如下内 ...

随机推荐

  1. jquery类似方法的比较(二)

    (1)append()&appendTo()&prepend()$prependTo() (2)after()&before()&insertAfter()&i ...

  2. JavaScript三(对象思想)

    JavaScript并不是面向对象的程序设计语言,但它是基于对象的.JavaScript中的每个函数都可用于创建对象,返回的对象既是该对象的实例,也是object的实例 . 一.对象与关联数组 Jav ...

  3. SVN跨版本库迁移目录并保留提交日志

    现在有一份代码code在版本库reposA/dirB/下,现在想把它移动到reposB/dirAA/下,本来打算交给SA做,没想到SA似乎 也不太懂的样子.于是,自己在VPS搭建了一个svnserve ...

  4. 转!!CMPP 网关错误码说明

    http://www.163duanxin.com/msg/1753.htm CMPP错误码说明   与中国移动代码的对应关系. MI::zzzzSMSC返回状态报告的状态值为EXPIREDMJ:zz ...

  5. scrapy-redis分布式爬虫

    简介 Scrapy-Redis则是一个基于Redis的Scrapy分布式组件.它利用Redis对用于爬取的请求(Requests)进行存储和调度(Schedule), 并对爬取产生的项目(items) ...

  6. Jquery EasyUI插件

    属性 属性是定义在 jQuery.fn.{plugin}.defaults.比如,dialog 的属性是定义在 jQuery.fn.dialog.defaults. 事件 事件(回调函数)也是定义在 ...

  7. web项目读取classpath路径下面的文件

    首先分两大类按web容器分类 一种是普通的web项目,像用Tomcat容器,特点是压缩包随着容器的启动会解压缩成一个文件夹,项目访问的时候,实际是去访问文件夹,而不是jar或者war包. 这种的无论你 ...

  8. 远程终端登录软件MobaXterm

    提到SSH.Telnet等远程终端登录,我相信很多人想到的都是PuTTY[注A]. PuTTY足够成熟.小巧.专注核心任务,并且对编码等常见坑的处理并不缺乏,这其实都是优点.但PuTTY在额外功能上就 ...

  9. Smarty小结提纲

    Smarty:模板技术 实现功能:前后分离. 原理:主要通过Smarty核心类实现,调用display方法,将模板文件读取,用正则进行替换,替换完保存到临时文件,将临时文件加载到当前页面. 配置文件( ...

  10. 关于Serializable的一个形象的例子

    一.知识预备 根据使用Serializable的使用场景,可以发现所涉及的场景都是跨进程的,就是要做的事情不是在一个java进程中完成的,我们都知道java进程是基于jvm跑起来的,而每一个被创建出来 ...