执行回调的异步编程模型

异步操作通常用于执行完成时间较长的任务,例如打开较大的文件、连接远程计算机、查询数据库等等。它的好处是,这些耗时的操作被放到另外的线程中去执行,因此,主线程就可以继续执行其它的任务。

 

这样带来的好处是显而易见的——它可以让你的程序更加聪明。例如,你有一个客户端,需要保存数据到数据库,并且这个操作需要一个相对较长的时间。如果保存以同步方式进行,那么 ,当用户点击了保存以后,界面就被锁死,直到保存完成。但是此时,如果用户想在界面上做一些与数据无关的操作,却被前一个操作阻碍了,那么,这个界面就让人感觉很笨。此时,如果应用异步编程模型来完成数据保存操作,等完操作完成以后,给用户一个温馨的提示,用户体验将会得到改善。

 

.NET Framework 2.0以后对异步编程提供了很大的支持。它提供了两人种设计模式:使用IAsyncResult对象的异步操作和事件的异步操作。

 

本文讨论以IAsyncResult对象的异步操作,并且使用异步调用完成时执行回调的方法。

 

任何方法或者说函数都可以通过写出其委托,变成可异步调用的方法——就这么简单。

 

例如,用户需要通过ACDemo类的Dothings做一个很长时间的任务,这个任务每完成10%,会汇报一下进度。任务完成后,返回Finish async work的字样:

如果我们在main里直接调用这个方法,那么,这个方法被调用以后10秒后,返回“Finish async work”,下面的for语句才会被执行。

 

但是,我们假设Dothings和for循环中的DosomthingInMainThread没有关联,我们就可以考虑让这件事异步的进行,让DoingThings调用完成以后给我们发一个通知。

 

方法也很简单,首先,根据目标方法“Dothings”的签名,写一个委托:

  

然后,我们在Main函数里,把asyncCallDemo.Dothings赋给委托DothingsAsync。委托会通过魔术自动的提供对应方法的BeginInvoke()和EndInvoke方法()。

让我们调用其BeingInvoke方法(以下代码还不能执行):

 

BeginInvoke的签名如下:

 

IAsyncResult BeginInvoke(用户自定义变量... , AsyncCallBack callback, object state);

当它被调用的时候,它会把同步方法送入线程池,并返回一个IAsyncResult的对象,这个对象可以用来追踪异步执行方法的状态等信息。 

 

同步方法被送入线程池中以后被执行,由于其与主线程已经分开,因此,不会阻止主线程继续执行。一旦这个方法执行完成,那么,它就会去执行callback。

 

AsyncCallBack是一个委托,异步执行的方法完成后,就会回调这个委托。

 

state参数可以传递一个任意的对象。此对象将赋线IAsyncResult的AsyncState属性。

 

由于Dothings方法的返回值要在其执行完成以后才能获得,因此,我们调用EndInvoke方法来获得返回值。但是,一旦在主线程中调用EndInvoke方法,主线程将被阻止直至Dothings方法调用完成,因此,调用EndInvoke方法的的位置就变得至关重要了。在采用回调方法时,我们通常会把EndInvoke()的调用放在AsyncCallBack里。一旦Doingthigs在线程池中完成,就回调callback;callback中再调用EndInvoke(),阻止主线程;由于此时,Doingthings方法其实已经执行完成,所以,能够立即返回结果以callback处理。完成callback以后,继续执行主线程。

 

因此,在调用BeginInvoke之前,我们需要先创建一个调用EndInvoke的委托作为callback参数:

在这里,由于调用了EndInvoke(),所以,需要委托对象——caller。我们是通过把ar.AsyncState进行强制类型转换来得到caller。而之所以我们能把ar.AsyncState强制转换成DothingAsync的委托对象,是因此在调用caller.BeginInovke的时候,我们把caller作为第三个参数间接的传递给了IAsyncReslt的AsyncState属性。

 

至此,我们一个异步模式就小程序就完成了。让我们看一下运行结果:

 

 

我们看到,主线方法和异步方法同时进行。最后,附上完整的源代码。

 

 

初学.NET,水平有限,如有谬误,还望各位高人多多指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值