C#多线程之旅(4)——APM初探
源码地址:https://github.com/Jackson0714/Threads
原文地址:C#多线程之旅(4)——APM初探
C#多线程之旅目录:
C#多线程之旅(5)——同步机制介绍
C#多线程之旅(6)——详解多线程中的锁
更多文章正在更新中,敬请期待......
C#多线程之旅(4)——APM初探
先交代下背景,前面几张内容主要是介绍多线程的基本知识,这一章是因为正好接触到了APM(异步编程模型),发现APM真的很强大,其中有部分知识点涉及到了委托的BeginInvoke/EndInvoke,就由衷地想写下APM相关的知识。

强大的异步处理模型,不得不被它折服!
一、简单的串行执行程序


让我们看看这个程序的运行结果:

二、使用委托来实现APM
2.1 预备知识
不惧面试:委托/// <summary>
/// 定义一个泛型委托
/// </summary>
/// <typeparam name="T">输入参数</typeparam>
/// <typeparam name="TResult">返回值</typeparam>
/// <param name="arg">输入参数</param>
/// <returns name="TResult">返回值</returns>
private delegate TResult Func<T, TResult>(T arg);
对于这个定义,C#编译器会将这行代码编译成一个类定义,它的逻辑定义如下:
public sealed class Func<T, TResult> : MulticastDelegate
{
public Func(Object obj, IntPtr method);
public TResult Invoke(T arg);
public IAsyncResult BeginInvoke(T arg, AsyncCallback callback, Object obj);
public TResult EndInvoke(IAsyncResult result);
}
定义一个委托时,会生成一个BeginInvoke和EndInvoke方法的类。
当定义下面的委托时
public delegate void myDelegate(int value);
通过反编译工具ILSpy查看结果:

BeginInvoke:
1.第一个参数arg为委托定义相同的参数(可以为两个参数arg,和委托的签名相同),可以传入到委托引用的方法;
2.倒数第二个参数callback为回调方法,当BeginInvoke方法执行完后,会立即调用回调方法,如果callback=null,则不调用回调方法;
3.倒数第一个参数object给EndInvoke用的。
4.返回值为IAsyncResult类型的接口对象(实际上是AsynResult的类型实例)。该接口对象用途
a.传递参数,它包含了对调用了BeginInvoke的委托的引用,这里是Add方法的int类型的输入参数;
b.包含了BeginInvoke()的最后一个Object类型的参数
c.它可以鉴别是哪个方法的哪一次调用,因为通过同一个委托变量可以对同一个方法调用多次。
EndInvoke:
1.第一个参数接收BeginInvoke返回的IAnsyResult;
2.返回的TResult为委托引用的方法的返回值,这里是Add方法的int类型返回值
2.2 用委托来实现APM的原理

2.3 动手写个实现了APM的Code
通过上面的流程图,相信我们对委托来实现APM有了一定的理解,再来读读code,相信能更快地理解。注释仅作参考,有问题可以回复我哦!


让我们看看结果:

注意:
1.必须先将IAsyncResult转换为AsyncResult,才能获取到引用的委托,因为它没有包含在IAsyncResult接口的定义中;
2.Add方法的调用,AddCallback方法都是线程池线程调用的;
3.BeginInvoke的object参数可以为任何类型,例子中传递的是string类型的参数"I'm here!";
4.主线程执行的for循环和Add方法中线程是同时进行的,交替打印结果;
5.当异步的Add方法没有执行完毕,调用EndInvoke,则会阻塞当前线程池线程,只有异步方法执行完毕后,才会继续执行的代码;
6.Add方法执行完后,会自动调用回调方法AddCallback;
7.在调用EndInvoke可能抛出异常,所以需要加try/catch/finally,捕获EndInvoke的可能抛出的异常。
因为只是刚开始接触APM相关的知识,所以本篇只是写初探的内容,后面的章节会更多地介绍这方面的内容。希望得到园友们的支持!
作 者:
Jackson0714
出 处:http://www.cnblogs.com/jackson0714/
关于作者:专注于微软平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!
C#多线程之旅(4)——APM初探的更多相关文章
- C#多线程之旅(3)——线程池
v博客前言 先交代下背景,写<C#多线程之旅>这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很 ...
- C#多线程之旅(1)——介绍和基本概念
原文地址:C#多线程之旅(1)——介绍和基本概念 C#多线程之旅目录: C#多线程之旅(1)——介绍和基本概念 C#多线程之旅(2)——创建和开始线程 C#多线程之旅(3)——线程池 C#多线程之旅( ...
- C#多线程之旅(7)——终止线程
先交代下背景,写<C#多线程之旅>这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很多问题. ...
- C#多线程之旅~上车吧?
前言:前几天,写了一篇关于多线程使用的文章,[线程使用]用法得到不少博友的好评,博主这几天加班写文章,把剩下的高级使用给写完,期望可以得到博友的追赞吧,那么废话不多说,开始我们的C#高级用法之旅!! ...
- 【10】Python urllib、编码解码、requests、多线程、多进程、unittest初探、__file__、jsonpath
1 urllib urllib是一个标准模块,直接import就可以使用 1.1get请求 from urllib.request import urlopen url='http://www.nnz ...
- [转]NHibernate之旅(7):初探NHibernate中的并发控制
本节内容 什么是并发控制? 悲观并发控制(Pessimistic Concurrency) 乐观并发控制(Optimistic Concurrency) NHibernate支持乐观并发控制 实例分析 ...
- NHibernate之旅(7):初探NHibernate中的并发控制
本节内容 什么是并发控制? 悲观并发控制(Pessimistic Concurrency) 乐观并发控制(Optimistic Concurrency) NHibernate支持乐观并发控制 实例分析 ...
- NHibernate之旅(18):初探代码生成工具使用
本节内容 引入 代码生成工具 结语 引入 我们花了大量的篇幅介绍了相关NHibernate的知识.一直都是带着大家手动编写代码,首先创建数据库架构.然后编写持久化类和映射文件,最后编写数据操作方法.測 ...
- 多线程之旅(Thread)
在上篇文章中我们已经知道了多线程是什么了,那么它到底可以干嘛呢?这里特别声明一个前面的委托没看的同学可以到上上上篇博文查看,因为多线程要经常使用到委托.源码 一.异步.同步 1.同步(在计算的理解总是 ...
随机推荐
- iOS进阶_地图上定位的标志——大头针
一.添加大头针 地图使用的框架是MapKit 大头针走的是MKAnnotation协议 /* 注意:因为是满足协议MKAnnotation,所以没有MKAnnotation的系统大头针类,必须自定义大 ...
- 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换(JS版代码)
/** * Created by Wandergis on 2015/7/8. * 提供了百度坐标(BD09).国测局坐标(火星坐标,GCJ02).和WGS84坐标系之间的转换 */ //定义一些常量 ...
- centos/redhat安装mysql
1.从http://dev.mysql.com/downloads/repo/ 下载对应的rpm文件,我的是版本7,所以下载:mysql-community-release-el7-5.noarch. ...
- rdc21n(研发与设计综合讨论)博客开通了!
rdc21n是“Research and Design Comprehensive discussioN”,其中21表示Comprehensive discussioN中间的21个字母(不包含空格), ...
- XML dom
将文件解析为文档 三步过程 为了使用 XML 文件中的信息,必须解析文件以创建一个 Document 对象. Document 对象是一个接口,因而不能直接将它实例化:一般情况下,应用程序会相应使用一 ...
- Backpropagation反向传播算法(BP算法)
1.Summary: Apply the chain rule to compute the gradient of the loss function with respect to the inp ...
- wlan-mcs来自百度百科
工作原理 802.11n射频速率的配置通过MCS(Modulation and Coding Scheme,调制与编码策略)索引值实现.MCS调制编码表是802.11n为表征WLAN的通讯速率而提出的 ...
- python 实现简单排序
今天偶得一本神奇的算法秘笈,据编辑说是一本easy and intresting 的书,所以我就开始翻开了. 书中作者用的是C语言,我最近正啃python 所以想着用python来解决作者的提问. 这 ...
- 【TextBox】重写右键菜单
参考资料 http://bbs.csdn.net/topics/390324356 http://www.cnblogs.com/ycxy/archive/2012/10/09/2716852.htm ...
- java 泛型的几点备忘
1.在java虚拟机中是没有泛型的,所有泛型类的参数都会被擦除,如下: public void test(List<String> list, int num){} public void ...