您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

C# 5.0功能之Async一瞥的图文代码详解

2025/1/31 15:34:33发布18次查看
距离微软发布async ctp已经有个把月了吧,周围大家都在热议着async。如果你对async已经非常熟悉,那么,请直接略过……如果你跟我一样,只会一点点异步编程,但又觉得以前的异步编程比较麻烦,那么,让我们一起来探索一下下一代的c#会给我们带来什么。(async ctp同样对vb有支持的。)
本文的例子基于async ctp sp1 refresh完成。由于 async还处于ctp阶段,很多东西还在讨论,因此,也许待到c# 5.0发布的时候,细节还会变动。但是,大体的思路,概念应该是不会有什么变化了。
进入正题:
首先,要试用async功能,我们需要安装visual studio 2010 sp1和microsoft visual studio async ctp (sp1 refresh)。
我们首先设定一个简单的任务,分别来看一下,同步编程,利用回调进步异步编程和async编程的方法,然后来通过他们来分析一下,async到底是什么,它给我们带来了什么。
任务:
建立一个windows form应用程序,当点击按钮时,先显示一行字,例如,开始计算什么的,用以表示状态,然后计算从1到int.max/2的累加,并把结果显示出来。
同步我们会这么做:
首先,写一个函数来实现基本算法:
#region  do things                       public   long  dosomething( int  n)                      {                           long  result = 1;                           for  ( int  i = 1; i <= n; i++) { result += i; } return result; } #endregion
然后,添加一个按钮的click事件处理程序:
private void btnsync_click( object sender, eventargs e) { lblresult.text = "start to do something . . ." ; long value = dosomething( int .maxvalue / 2); lblresult.text = value.tostring(); }
代码第一行改写label的字样;第二行调用算法获得结果;第三行把结果输出。看似挺不算的。运行一下,就会发现有两个问题:
这个算法需要四五秒钟左右的实现时间,并且在这几秒钟的时间里,界面是锁死的,也就是说应用程序就像死了一样,它不接受任何用户操作。(也许我的电脑比较差,呵呵,所以,如果你没有遇到这种情况,请加大输入参数的值,让它算一会儿。)
我们没有看到start to do something这一行字。
ok,出现这个现象也是可以理解的,因为我们把大量的运算添加到了ui线程里面了。所以,解决方法就是把它放到外面。我试了一下不用async,实现的代码如下:
private void btncallback_click( object sender, eventargs e) { lblresult.text = "start to do something . . ." ; func< int , long > callbackdelegate =  this .dosomething;             callbackdelegate.begininvoke(                               int .maxvalue / 2,                               new  asynccallback(                              a =>                              {                                  lblresult.invoke( new  methodinvoker(() =>                                      {                                          lblresult.text = callbackdelegate.endinvoke(a).tostring();                                      }));                              }),                               null );                      }
如果你觉得这段代码比较晕,那就跳过这一节吧。可能我代码写得不好,大家将就看我简单解释一下,我首先给dosomething写了一个代理,然后,调用了代理的begininvoke方法,把算法放到了其它的thread中去调用了。这个代理执行完了以后,因为它不会直接返回一个long型的值,而是会去执行一个asynccallback,所以,就在这个callback里,去调用这个代理的endinvoke()。
好吧,且不论代码质量,这个就是有async之前的一种实现异步的方法。
从这个代码里,我们完全看不到原来代码的影子,我也没有办法像解释同步代码一样解释:第一、第二、第三……有了async之后呢?呵呵,代码说明一切:
public   task < long > dosomethingasync( int  n)                      {                          return   taskex .run< long >(() => dosomething(n));                      }            private   async   void  btnasync_click( object  sender,  eventargs  e)                      {                          lblresult.text =  start do something... ;                           var  x =  await  dosomethingasync( int .maxvalue / 2);                          lblresult.text = x.tostring();                      }
三件事:
第一:添加文件引用:asyncctplibrary.dll。相信async正式发布之后,这个会出现在.net应用程序集里。
第二:把dosomething封装成一个task。
第三:添加一些关键字,例如async,例如await。
我们来仔细看一下代码:
首先,我把要异步执行的代码的返回值写成task<t>。这个返回值其实有三个选项:void,task和task<t>,具体怎么用,大家查msdn上c#4.0中的task类吧。
然后,我调用了taskex中的run<long>方法,传递给它一个返回值为long的方法——就是我们的任务的算法啦。
如果你有兴趣研究,可以看一下run<t>其实调用了task.factory.startnew<t>,而这个start<new>则是先建了一个task,然后调用了它的start方法……
好,把算法封成任务部分完成。
第二部分代码比较容易解释了:
第一行改写label的字样;第二行调用算法获得结果;第三行把结果输出。<--本行复制/粘贴自前文:-)
呵呵,让我们看看细一点,比较一下sync和async的代码:
sync
async
private void btnsync_click(object sender, eventargs e)
{
lblresult.text = start to do something . . .;
long value = dosomething(int.maxvalue / 2);
lblresult.text = value.tostring();
}
private async void btnasync_click(object sender, eventargs e)
{
lblresult.text = start do something...;
var x = await dosomethingasync(int.maxvalue / 2);
lblresult.text = x.tostring();
}
首先,我们在方法名上加上async修饰,声明这是一个有异步调用的方法;
然后,我们在返回task<t>的函数调用(dosomethingasync)之前添加一个await关键字。来猜猜看x是什么类型的?答案是long型。有了await之后,即使在设计时,编译器会自动把task<t>的类型,转换成t类型。
代码到这里结束了,但是,新的async功能给我们带来了什么?是异步编程的能力吗?我们用callback同样可以实现异步,而iasynccallback接口应该在.net 1.1中已经实现了;多线程的命名空间也早就存在;task在c# 4.0中被引入……
我想,async给程序员带来的是一种代码逻辑为中心并且实现多线程编程的方式。通过最后的比较,我们看到,async的代码与sync的代码相差无几,程序不再需要花大量精力去考虑回调、同步等等的问题……这与c#一直在努力的方向是一致的,程序员更多的来描述是什么而不是怎么做。
最后,附上应用程序下载和源代码,还有运行界面截图……(好吧,我不是美工,请原谅 :-) )
点击下载源代码
点击async,看到运行提示:
显示执行结果:
最新最官方的async资料在这儿:^v^
http://msdn.microsoft.com/async
以上就是c# 5.0功能之async一瞥的图文代码详解的内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product