你的位置:首页 > ASP.net教程

[ASP.net教程].NET4.5新特性async和await修饰符实现异步编程


开篇

每一个版本的.net都会引入一些新的特性,这些特性方便开发人员能够快速实现一些功能。虽然.net版本一直在更新,但是新版本对旧版本的程序都是兼容的,在这一点上微软做的还是非常好的。每次学一个新内容,第一次接触的方法在脑海里占的位置还是比较重要的,从刚开始接触.net的多线程编程是使用Thread类,然后后面写的程序只要用到异步或者多线程就马上会想到用Thread,虽然知道委托的异步调用也能够实现,但是脑海里面的排在前面还是Thread类,在那个时候不知道他们之间的区别和优劣,也就不懂得如何去取舍。到了.net4.0引入了Task这个任务类,让我们用少量的代码就开始实现了多线程编程,从这个时候开始我也慢慢的了解了.net里面的有哪一些异步实现的方式以及多线程内部的一些机制,也知道它们各自的优势。在接触Task类的时候.net4.5也发布出来了,并且带来一个更加方便的关键字(async,await),轻松实现函数异步调用。虽然知道async和await修饰符,但是自己却迟迟没有接触,因为平常的工作中使用Task类就基本能实现我想要的效果。最近看了一些源码,源码中有很多代码是应用了async和await的关键字来实现异步的,所以我也不得不去学习,接触之后发现,使用async和await关键字确实简化了以前异步编程所需要的步骤,也比较好理解。下面通过一些小例子来简述async和await修饰符如何实现异步编程以及和以前使用Task类来实现异步编程的少许区别。另外,关于.net4.0(包含)以前的的异步编程模式可以参考我的另外一篇博文:http://www.cnblogs.com/mingjiatang/p/5267391.html

1 async和await实现方法异步调用

下面看一段由async定义的异步方法以及异步方法的调用代码,如下:
 
    static void Main(string[] args)    {      AsyncMethod(10);//no.1      Console.WriteLine("执行其他的东西,当前线程id:{0}", Thread.CurrentThread.ManagedThreadId);//out.4      Console.ReadKey();    }    static async void AsyncMethod(int i)    {      Console.WriteLine("异步方法开始,当前线程id:{0}",Thread.CurrentThread.ManagedThreadId);//out.1      await AsyncTaskMethod(i);//no.3      Console.WriteLine("异步方法退出,当前线程id:{0}", Thread.CurrentThread.ManagedThreadId);////out.6    }    public static async Task<int> AsyncTaskMethod(int i)    {      Console.WriteLine("【任务】开始,当前线程id:{0}", Thread.CurrentThread.ManagedThreadId);//out.2      Task<int> t = Task.Run(() =>      {        Console.WriteLine("【任务】正在执行,执行任务的线程id:{0}", i, Thread.CurrentThread.ManagedThreadId);//out.3        Thread.Sleep(2000);        return i;      });//no.4            int r= await t;//no.5      Console.WriteLine("【任务】执行完成,当前线程id:{0}", i, Thread.CurrentThread.ManagedThreadId);//out.5      return r;    }

下面是执行结果:




 
----------------async和await的语法使用结合代码--------------------
 
在解释程序的执行原理之前,先介绍一下async和await关键的语法,async只能修饰方法和lambda表达式或者匿名方法,await通常应用于Task或Task<TResult>对象前,用于等待任务完成。
 
-----------------解释程序的执行过程-----------------------------------
 
1、主线程【9】进入Main方法,执行no.1异步方法。
2、主线程【9】进入异步方法AsyncMethod内部,执行out.1。
3、主线程【9】执行no.3异步任务方法,由于no.3表达式前面await关键字修饰,所以要等待任务完成之后才会执行out.6。
4、主线程【9】进入异步任务方法AsyncTaskMethod内部,执行out2。
5、开始执行Task任务,程序从线程池中获取一个任务线程【10】执行no.4的任务。
6、任务线程【10】开始任务,执行out.3;
7、在线程【10】执行任务的同时,主线程【9】同步运行,当执行到no.5时,遇到await关键字,会一直等待任务的完成,不会再执行下面的out.5,因此主线往上返回Main方法中,执行out.4,到此,主线程的代码执行完毕。
8、任务线程【10】执行任务完成,然后再执行no.5后面的代码out.5,最后返回任务执行的结果。
9、这时no.3一直等待的任务已经执行完毕,再从线程池中开启一个线程【6】调用no.3之后的代码。

10、到此整个程序就执行完毕了。

小结

其实在async和await关键字的异步实现依然是使用线程池中的线程。个人认为,内部是使用Task类实现的,只是在任务结束时的回调比单独使用Task要简单一些。单独使用Task类实现异步时,当任务完成要进行回调,需要对Task对象调用ContinueWith方法,绑定任务结束后的回调函数并传递相关参数。而使用async和await实现异步时,只需要使用Task去执行任务,然后用await去等待任务执行的结果就好了,并不会阻塞主线程的运行,整个编码过程和同步实现差不多,这个例子就是一个很好的说明。
 
--------------------------------最后再说明一下async和await使用要点和作用------------------------------------------
1、异步的方法(包括匿名方法,和lambda表达式)必须要使用async修饰
2、异步方法可以具有返回类型的 void, Task,或 Task< TResult> 。该方法不能声明任何 ref 或 出参数,尽管它可以调用具有此类参数的方法。其中返回值为TRsult时,返回类型就是 Task< TResult>。
3、await 运算符应用于一个异步方法的任务挂起方法的执行,直到等待任务完成。 任务表示正在进行的工作。
4、await 表达式不阻止调用它的线程。  当任务完成时,将会调用其延续任务,并且,异步方法的执行恢复它将会停止的位置。换句话说就是:await会让当前方法等待Task执行完毕再执行。



去海南的旅游团价格去海南旅游必去景点去海南旅游要多少钱去海南旅游最佳路线去海南旅游最佳时间卢浮宫门票_卢浮宫博物馆门票_法国卢浮宫门票价格 卢浮宫简介_卢浮宫博物馆简介_法国卢浮宫博物馆简介 观看现场分割鱼 畅品夏威夷果 夏威夷在哪里_美国夏威夷属于哪个洲_夏威夷在哪个国家 2011抓机遇四川提升旅游战略地位 导游走进中南海 2011谋大势四川奠基旅游经济强省 全国导游大赛颁奖晚会在京举办 莫干山漂流回起点有班车吗?德清莫干山漂流回程班车收费吗? 岑溪天龙顶自驾游攻略?岑溪到天龙顶国家山地公园要多久? 岑溪到天龙顶有多远?岑溪到天龙顶山地公园多少公里? 岑溪到天龙顶怎么走?岑溪到天龙顶山地公园自驾车路线? 香港哪里可以买到手表?哪里有表行? 去香港买戒指哪里好?香港有哪些珠宝店? 澳门一日游能游览澳门全部景点吗?路线怎么安排? 香港有哪些种类的手表?怎样买到货真价实的手表? EOH-FTWUPB0-EN Datasheet EOH-FTWUPB0-EN Datasheet EOH-FTWUPB0-GG Datasheet EOH-FTWUPB0-GG Datasheet EOH-FTYUCB0-KG Datasheet EOH-FTYUCB0-KG Datasheet 山西省香港旅游报价 山西省香港旅游报价 山西省香港旅游报价 成都香港游报价 成都香港游报价 成都香港游报价 包头去香港游报价 包头去香港游报价 包头去香港游报价