本文的例子基于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) |
private async void btnAsync_Click(object sender, EventArgs e) |
起首,我们在要领名上加上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一瞥的图文代码详解的内容,更多相关内容请关注ki4网(www.ki4.cn)!