Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,Begin
http://www.chenjiliang.com/Article/View.aspx?ArticleID=2071
让我们来看看同步异步的区别:
同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作
.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。
因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟
相比来说,在某些条件下选择异步方法调用就可能更好一些
例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法
.NET Framework允许异步调用任何方法,定义与需要调用的方法具有相同签名的委托
CLR将自动为该委托定义添加适当签名的BeginInvoke虚方法和EndInvoke虚方法和Invoke方法。
关于委托的这3个方法的详细说明可以参考这文章
http://www.cnblogs.com/aierong/archive/2005/05/25/162181.html
我们先来了解这2个方法和一个委托和一个接口:
(1)BeginInvoke方法用于启动异步调用
它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数,将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的
AsyncState 属性获得)作为最后两个参数,如没有可以为空.
BeginInvoke立即返回,不等待异步调用完成。
BeginInvoke返回IasyncResult,可用于监视调用进度。
结果对象IAsyncResult是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。
结果对象被传递到结束操作,该操作返回调用的最终返回值。
在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的代码可以调用结束操作。
(2)EndInvoke方法用于检索异步调用结果。
在调用BeginInvoke后可随时调用EndInvoke方法,注意:始终在异步调用完成后调用EndInvoke.
如果异步调用未完成,EndInvoke将一直阻塞到异步调用完成。
EndInvoke的参数包括需要异步执行的方法的out和ref参数以及由BeginInvoke返回的IAsyncResult。
要注意的是,始终在异步调用完成后调用EndInvoke
(3)AsyncCallback委托用于指定在开始操作完成后应被调用的方法
AsyncCallback委托被作为开始操作上的第二个到最后一个参数传递
代码原型如下:
[Serializable] public delegate void AsyncCallback(IAsyncResult ar);
(4)IAsyncResult接口
它表示异步操作的状态.
该接口定义了4个公用属性
实际上,发起和完成.NET异步调用有4种方案可供你选择
1.方案1-自己调用EndInvoke方法
异步执行方法的最简单方式是以BeginInvoke开始,对主线程执行一些操作,然后调用EndInvoke,EndInvoke直到异步调用完成后才返回
还是先来段自己喜欢的控制台代码:
复制 保存
using System; namespace ConsoleApplication1 { class Class1 { public delegate void AsyncEventHandler(); void Event1() { Console.WriteLine("Event1 Start"); System.Threading.Thread.Sleep(2000); Console.WriteLine("Event1 End"); } void Event2() { Console.WriteLine("Event2 Start"); int i = 1; while (i < 1000) { i = i + 1; Console.WriteLine("Event2 " + i.ToString()); } Console.WriteLine("Event2 End"); } void CallbackMethod(IAsyncResult ar) { ((AsyncEventHandler) ar.AsyncState).EndInvoke(ar); } [STAThread] static void Main(string[] args) { long start = 0; long end = 0; Class1 c = new Class1(); Console.WriteLine("ready"); start = DateTime.Now.Ticks; AsyncEventHandler asy = new AsyncEventHandler(c.Event1); IAsyncResult ia = asy.BeginInvoke(null, null); c.Event2(); asy.EndInvoke(ia); end = DateTime.Now.Ticks; Console.WriteLine("时间刻度差=" + Convert.ToString(end - start)); Console.ReadLine(); } } }
此程序简单,异步的处理过程在代码43-46这几行
结果如下:
现在让我们来看看同步处理
修改代码43-46这几行代码:
c.Event1(); c.Event2();
结果如下:
前者的时间刻度大大小于后者
我们可以明显地看到异步运行的速度优越性
2.方案2-采用查询(IsCompleted属性)
IAsyncResult.IsCompleted属性获取异步操作是否已完成的指示,发现异步调用何时完成.
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1); IAsyncResult ia = asy.BeginInvoke(null, null); c.Event2(); while (!ia.IsCompleted) { } asy.EndInvoke(ia);
3.方案3-采用AsyncWaitHandle来等待方法调用的完成
IAsyncResult.AsyncWaitHandle属性获取用于等待异步操作完成的WaitHandle
WaitHandle.WaitOne方法阻塞当前线程,直到当前的WaitHandle收到信号
使用WaitHandle,则在异步调用完成之后,但在通过调用EndInvoke结果之前,可以执行其他处理
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1); IAsyncResult ia = asy.BeginInvoke(null, null); c.Event2(); ia.AsyncWaitHandle.WaitOne();
4.方案4-利用回调函数
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法 要使用回调方法,必须将代表该方法的AsyncCallback委托传递给BeginInvoke
再次修改代码43-46这几行代码:
AsyncEventHandler asy = new AsyncEventHandler(c.Event1); asy.BeginInvoke(new AsyncCallback(c.CallbackMethod), asy); c.Event2();
希望上面提到的知识对你有所提示
当然欢迎交流和指正
本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/618307 ,如需转载请自行联系原作者
Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,Begin相关推荐
- Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)...
收藏地址 http://aierong.cnblogs.com/archive/2005/05/25/162308.html 让我们来看看同步异步的区别: 同步方法调用在程序继续执行之前需要等待同步 ...
- Mcad学习笔记之委托再理解(delegate的构造器,MulticastDelegate,BeginInvoke,EndInvoke,Invoke4个方法的探讨)...
相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...
- Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法)
相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...
- Mcad学习笔记之Microsoft Windows服务
相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...
- C# 学习笔记——PL 并行编程 TPL 和传统 .NET 异步编程
C# 学习笔记--PL 并行编程 TPL 和传统 .NET 异步编程 Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Fa ...
- Python学习笔记:异步IO(3)
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- Python学习笔记:异步IO(2)
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- Python学习笔记:异步IO(1)
前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...
- java学习笔记15--多线程编程基础2
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...
最新文章
- git clone 一部分_Git/GitHub 中文术语表 | Linux 中国
- 在envi做随机森林_随机森林原理
- RedHat7.0 设置weblogic开机自启动
- 微信突然出现redirect_uri 参数错误
- html dot标签,html – CSS Dot符号命名约定
- 后端:Java 8 中的 Map 实用操作,学习下!
- 《Unit Testing》2.1 经典学派如何做测试隔离
- PHP冒泡排序(Bubble Sort)算法详解
- python安装多久_(一)安装Python
- 2013.8.4thinkPHp学习
- SVN更新无数次后仍显示Out of date
- 千图成像python_Python---如何实现千图成像:初级篇(从图片爬取到图片合成)
- 视频教程-网页设计速成之Dreamweaver-Dreamweaver
- 【干货】APP解构重构,让你用户不再流失
- python京东自动签到_利用python Selenium实现自动登陆京东签到领金币功能
- 肠道微生物群与心血管疾病:机遇与挑战
- 如何通过组策略控制远程主机空闲时间自动断开并注销
- 计算机木马的作用,详细介绍计算机木马下篇-1
- 什么是智能双线机房和BGP智能双线机房的原理
- wireshark三次握手抓包
热门文章
- 【报告分享】万物互联时代的操作系统报告(附下载)
- 学生网页作业 web网页设计实例作业 家乡旅游网站设计——家乡旅游-榆林子州(8页) 出游旅游主题度假酒店 计划出行网站设计
- socket.io前后端实践及转发、多服务问题
- 执行力七准则---工作中如何破解困难提高执行力
- 【Elastic Search权威指南 读书小记3】ES之数据操作
- 对深色(黑夜)模式的执着追求
- 丁磊进退之道《前程密码》
- 分享 :准备数据时如何避免数据泄漏
- [附源码]JAVA毕业设计家庭记账系统(系统+LW)
- 贝壳团队出品的 Flutter 组件库 Bruno 现已开源