博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mcad学习笔记之异步编程(AsyncCallback委托,IAsyncResult接口,Begin
阅读量:6421 次
发布时间:2019-06-23

本文共 3271 字,大约阅读时间需要 10 分钟。

让我们来看看同步异步的区别: 

同步方法调用在程序继续执行之前需要等待同步方法执行完毕返回结果 
异步方法则在被调用之后立即返回以便程序在被调用方法完成其任务的同时执行其它操作 
.NET框架基类库中有好几种类都可以提供同步和异步的方法调用。 
因为同步方法调用会导致程序流程中途等待,所以采用同步方法的情况下往往会导致程序执行的延迟 
相比来说,在某些条件下选择异步方法调用就可能更好一些 
例如,有的时候程序需要给多个Web服务发出请求,还有远程处理信道(HTTP、TCP)和代理,这时就最好采用异步方法 
.NET Framework允许异步调用任何方法,定义与需要调用的方法具有相同签名的委托 
CLR将自动为该委托定义添加适当签名的BeginInvoke虚方法和EndInvoke虚方法和Invoke方法。 
关于委托的这3个方法的详细说明可以参考这文章 
 
我们先来了解这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(nullnull); c.Event2(); asy.EndInvoke(ia); end = DateTime.Now.Ticks; Console.WriteLine("时间刻度差=" + Convert.ToString(end - start)); Console.ReadLine(); } } }

此程序简单,异步的处理过程在代码43-46这几行 

结果如下: 
单击显示全图,Ctrl+滚轮缩放图片 
现在让我们来看看同步处理 
修改代码43-46这几行代码:

c.Event1(); c.Event2();

结果如下: 

单击显示全图,Ctrl+滚轮缩放图片 
前者的时间刻度大大小于后者 
我们可以明显地看到异步运行的速度优越性 
2.方案2-采用查询(IsCompleted属性) 
IAsyncResult.IsCompleted属性获取异步操作是否已完成的指示,发现异步调用何时完成. 
再次修改代码43-46这几行代码:

AsyncEventHandler asy = new AsyncEventHandler(c.Event1); IAsyncResult ia = asy.BeginInvoke(nullnull); 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(nullnull); 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 ,如需转载请自行联系原作者

你可能感兴趣的文章
【编译打包】tengine 1.5.1 SRPM
查看>>
看图说话:手动清除病毒文件流程
查看>>
一句话下拖库
查看>>
Deploy Office Communications Server 2007R2 Group Chat Server(二)
查看>>
在Cacti上实现MSN报警机制
查看>>
如何对C++虚基类构造函数
查看>>
XFire WebService开发快速起步
查看>>
JavaScript 函数replace揭秘
查看>>
QTP解决内嵌IE窗体方法2
查看>>
“王子”的演讲:N828印象
查看>>
判断JS字符串中是否包含某些字符
查看>>
Phalanger---PHP的.NET编译器
查看>>
Scanner----java控制台和文件读取的利器(java 5新增)
查看>>
怎样解决spoolsv.exe应用程序错误
查看>>
Android应用程序键盘(Keyboard)消息处理机制分析(25)
查看>>
如何安全设定和检测你的密码安全性?
查看>>
一例HP ADG数据恢复成功(8×73GB SCSI)
查看>>
虚拟化系列-Citrix XenServer 6.1 XenMotion与HA
查看>>
《3D数学基础》2.1 矩阵基本概念、2.2 矩阵的数乘和加减法、2.3 方阵
查看>>
TFS创建团队项目(三)
查看>>