异步编程

委托类有两个方法, 叫做BeginInvoke和EndInvoke

当我们调用委托的BeginInvoke方法时,它开始在线程池中的独立线程上执行引用方法,并且立即返回原始线程, 原始线程可以继续, 而引用方法会在线程池的线程中并行执行

当程序希望获取已完成的异步方法的结果时, 可以检查BeginInvoke返回的IAsyncResult的IsCompleted属性, 或调用委托的EndInvoke方法来等待委托完成.

在 等待--直到完成 模式中,在发起了异步方法以及做了一些其他处理之后,原始线程就中断并且等异步方法完成之后再继续

在 轮询 模式中, 原始线程定期检查发起的线程是否完成, 如果没有则可以继续做一些其他的事情.

在 回调 模式中, 原始线程一直执行, 无需等待或检查发起的线程是否完成 , 在发起的线程中的引用方法完成之后, 发起的线程就会调用回调方法, 有回调方法在调用EndInvoke之前处理异步方法的结构.

在调用BeginInvoke时,参数列表中的实参数组组成如下:

引用方法需要的参数;

两个额外的参数-----callback参数和state参数

BeginInvoke从线程池中获取一个线程并且在新的线程开始时运行引用方法

BeginInvoke返回给调用线程一个实现IAsyncResult接口的对象.这个接口应用包含了异步方法的当前状态, 原始线程然后可以继续执行

之后的行声明了一个叫del的Mydel委托类型的委托对象,并且使用Sum方法来初始化它的调用列表

最后一行代码调用了委托对象的BeginInvoke方法并且提供了两个委托参数3和5, 以及两个BeginInvoke的参数callback和state, 在本例中都设为null. 执行后, BeginInvoke方法进行两个操作:

从线程池中获取一个线程并且在新的线程上开始运行Sum方法,提供它3和5作为参数.

它收集新线程的状态信息并且把IAsyncResult接口的引用返回给调用线程来提供这些数据.

调用线程把它保存在一个叫做iar的变量中.

EndInvoke方法用来获取由异步方法调用返回的值,并且释放线程使用的资源. EndInvoke有如下的特性:

它接受一个由BeginInvoke方法返回的IAsyncResult对象的应用, 并找到它关联的线程.

如果线程池的线程已经退出, EndInvoke做如下的事情:

它清理退出线程的状态并且释放它的资源

它找到引用方法返回的值并且把它的值作为返回值

如果当EndInvoke被调用时线程池的线程仍然在运行,调用线程就会停止并且等待. 直到清理完毕并且返回值. 因为EndInvoke是为开启的线程进行清理, 所以必须确保对每一个BeginInvoke调用EndInvoke.

如果异步方法触发了异常,在调用EndInvoke时会抛出异常.

AsyncResult类

当我们调用委托对象的BeginInvoke方法时,系统创建了一个AsyncResult类的对象. 然而,它不返回类对象的引用. 而是返回对象中包含的IAsyncResult接口的引用.

AsyncResult对象包含一个叫做AsyncDelegate的属性, 它返回一个指向被调用来开启异步方法的委托的引用, 但是, 这个属性是类对象的一部分而不是接口的一部分.

IsCompleted属性返回一个布尔值, 表示异步方法是否完成.

AsyncState属性返回一个对象的引用, 它被作为BeginInvoke方法调用时的state参数. 它返回Object类型的引用

回调模式

在之前的等待---直到结束模式以及轮询模式中, 初始线程继续它自己的控制流程, 直到它知道开启的线程完成, 然后, 它获取结果并继续.

回调模式的不同之处在于, 一旦线程发起了异步方法, 它就自己管自己了, 不再考虑同步. 当异步方法调用结束之后, 系统调用一个用户自定义的方法来处理结果, 并且调用委托的EndInvoke方法.这个用户自定义的方法叫做回调方法或回调.

BeginInvoke的参数列表中最后两个额外参数被回调方法使用:

第一个参数为callback, 是回调方法的名字

第二个参数为state,可以是null护着是要传入回调方法的一个对象的引用,我们可以通过使用IAsyncResult参数的AsyncState属性来获取这个对象,参数的类型为object

给回调方法的参数只有一个, 就是刚结束的异步方法IAsyncResult接口的引用, IAsyncResult接口对象在AsyncResult类对象的内部.

尽管IAsyncResult接口没有委托对象的引用, 而包含它的AsyncResult类对象却有委托对象的引用. 所以, 示例代码方法体的第一行就通过转换接口引用为类类型来获取类对象的引用. 变量ar现在就有类对象的引用.

有了类对象的引用 , 我们现在就可以调用类对象的AsyncDelegate属性并且把它转化为合适的委托类型.,这样就得到了委托引用, 我们可以用它来调用EndInvoke.

其实一开始传入的参数iar就是AsyncResult类型的,只是设为了IAsyncResult类型,后来又转换回来了而已,所以是符合里氏代换原则的

时间: 2024-10-16 23:36:27

异步编程的相关文章

Python Twisted网络编程框架与异步编程入门教程

原作出处:twisted-intro-cn 作者:Dave 译者:杨晓伟 luocheng likebeta 转载声明:版权归原作出处所有,转载只为让更多人看到这部优秀作品合集,如果侵权,请留言告知 感 谢:感谢 杨晓伟 luocheng likebeta 为国内Twisted Coder做的里程碑级贡献 其 它:能访问到Github的童鞋,请访问出处链接.因为出处排版相当棒! 1.Twisted理论基础 2.异步编程初探与reactor模式 3.初次认识Twisted 4.由twisted支持

利用 Python yield 创建协程将异步编程同步化

在 Lua 和 Python 等脚本语言中,经常提到一个概念: 协程.也经常会有同学对协程的概念及其作用比较疑惑,本文今天就来探讨下协程的前世今生. 首先回答一个大家最关心的问题:协程的好处是什么? 通俗易懂的回答: 让原来要使用 异步 + 回调 方式写的非人类代码,可以用看似同步的方式写出来. 1.回顾同步与异步编程 同步编程即线性化编程,代码按照既定顺序执行,上一条语句执行完才会执行下一条,否则就一直等在那里. 但是许多实际操作都是CPU 密集型任务和 IO 密集型任务,比如网络请求,此时不

探索Javascript 异步编程

在我们日常编码中,需要异步的场景很多,比如读取文件内容.获取远程数据.发送数据到服务端等.因为浏览器环境里Javascript是单线程的,所以异步编程在前端领域尤为重要. 异步的概念 所谓异步,是指当一个过程调用发出后,调用者不能立刻得到结果.实际处理这个调用的过程在完成后,通过状态.通知或者回调来通知调用者. 比如我们写这篇文字时点击发布按钮,我们并不能马上得到文章发布成功或者失败.等待服务器处理,这段时间我们可以做其他的事情,当服务器处理完成后,通知我们是否发布成功. 所谓同步,是指当一个过

JavaScript异步编程

在一年前初学js的时候,看过很多关于异步编程的讲解.但是由于实践经验少,没有办法理解的太多,太理论的东西也往往是看完就忘. 经过公司的三两个项目的锻炼,终于对js异步编程有了比较具体的理解.但始终入门较浅,在这里就当是给自己一个阶段性的总结. 在异步编程中,一条语句的执行不能依赖上一条语句执行完毕的结果,因为无法预测一条语句什么时候执行完毕,它与代码顺序无关,语句是并发执行的. 例如以下代码:     1 $.get($C.apiPath+'ucenter/padCharge/findMembe

【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就具体看看编译器到底在背后帮我们做了哪些复杂的工作的. 二.同步代码存在的问题 对于同步的代码,大家肯定都不陌生,因为我们平常写的代码大部分都是同步的,然而同步代码却存在一个很严重的问题,例如我们向一个Web服务器发出一个

让我们再为C#异步编程Async正名

本文版权归博客园和作者吴双本人共同所有.转载和爬虫必须在显要位置注明出处:http://www.cnblogs.com/tdws 半年前翻译了一系列很糟糕的异步编程文章,用异步的常用语来说:"在将来的某个时间" 我还会重新翻译Async in C#5.0 http://www.cnblogs.com/tdws/p/5617242.html 写在前面 异步编程在处理并发方面被使用的越来越多,之所以说上面一句话,是为了区分多线程编程.各位司机都知道,实际上异步编程的核心目标正并发处理.可还

异步编程系列第04章 编写Async方法

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,愿爱技术的园友们在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力而

异步编程系列第03章 自己写异步代码

p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提高下英文,用我拙劣的英文翻译一些重要的部分,纯属娱乐,简单分享,保持学习,谨记谦虚. 如果你觉得这件事儿没意义翻译的又差,尽情的踩吧.如果你觉得值得鼓励,感谢留下你的赞,愿爱技术的园友们在今后每一次应该猛烈突破的时候,不选择知难而退.在每一次应该独立思考的时候,不选择随波逐流,应该全力以赴的时候,不选择尽力而

Javascript异步编程的4种方法

转自 阮一峰 http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html 作者: 阮一峰 日期: 2012年12月21日 你可能知道,Javascript语言的执行环境是"单线程"(single thread). 所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推. 这种模式的好处是实现起来比较简单,执行环境

C#基础___异步编程

C#异步编程_0 三种常见模式:1.async/await    2.Background类    3.BeginInvoke/EndInvoke 一.async/await 代码示例: class Program { static void Main() { Task<int> value = DoAsyncStuff.Handing(5, 6); } } static class DoAsyncStuff { public static async Task<int> Hand