开篇

每一个版本的.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执行完毕再执行。

.NET4.5新特性async和await修饰符实现异步编程的更多相关文章

  1. 四、C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 .NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两个关键字简化了异步编程,之所以简化了,还是因为编译器给我们做了更多的工作,下面就 ...

  2. 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...

  3. 转:[你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  4. [你必须知道的异步编程]C# 5.0 新特性——Async和Await使异步编程更简单

    本专题概要: 引言 同步代码存在的问题 传统的异步编程改善程序的响应 C# 5.0 提供的async和await使异步编程更简单  async和await关键字剖析 小结 一.引言 在之前的C#基础知 ...

  5. async和await是如何实现异步编程?

    目录 异步编程样例 样例解析 浅谈Promise如何实现异步执行 参考 1.异步编程样例 样例: // 等待执行函数 function sleep(timeout) { return new Prom ...

  6. C# 5.0 新特性——Async和Await使异步编程更简单

    http://www.cnblogs.com/zhili/archive/2013/05/15/csharp5asyncandawait.html http://blog.zhaojie.me/201 ...

  7. 使用ES6新特性async await进行异步处理

    我们往往在项目中会遇到这样的业务需求,就是首先先进行一个ajax请求,然后再进行下一个ajax请求,而下一个请求需要使用上一个请求得到的数据,请求少了还好说,如果多了,就要一层一层的嵌套,就好像有点c ...

  8. 转 .NET4.5之初识async与await

    来自:http://www.cnblogs.com/lekko/archive/2013/03/05/2944282.html 本人是从.NET4.0刚出的时候接触的.NET环境,所以学的东西就是4. ...

  9. NET4.5之初识async与await

    这是两个关键字,用于异步编程.我们传统的异步编程方式一般是Thread.ThreadPool.BeginXXX.EndXXX等等.把调用.回调分开来,代码的逻辑是有跳跃的,于是会导致思路不是很清晰的问 ...

随机推荐

  1. .NET Windows Form 改变窗体类名(Class Name)有多难?

    研究WinForm的东西,是我的一个个人兴趣和爱好,以前做的项目,多与WinForm相关,然而这几年,项目都与WinForm没什么关系了,都转为ASP.NET MVC与WPF了.关于今天讨论的这个问题 ...

  2. 初识PHP之php运行流程及原理(一)

    初识PHP一.用脚本命令行运行php(1)打开cmd.exe(winkey+R)(2)找到php.exe(拖进cmd即可)(3)输入命令php.exe -f "文件实际路径"注:运 ...

  3. 【bzoj5180】[Baltic2016]Cities 斯坦纳树

    这题一看显然是一个裸的斯坦纳树 我们用$f[i][j]$表示经过的路径中包含了状态$i$所表示的点,且连接了$j$号点的最短路径. 显然,$f[i][j]=min\{f[i$^$k][j]+f[k][ ...

  4. 剑指offer五十二之正则表达式匹配

    一.题目 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...

  5. (转)python 判断数据类型

    原文:https://blog.csdn.net/mydriverc2/article/details/78687269 Python 判断数据类型有type和isinstance 基本区别在于: t ...

  6. 免密sudo su

    1.添加文件 /etc/sudoers.d/wsy_sudoers %wsy-sudoers ALL=(ALL:ALL) NOPASSWD:ALL 2.添加用户组 groupadd wsy-sudoe ...

  7. Fiddler Web Debugger的截断功能(图文详解)

    不多说,直接上干货! Fiddler的重头好戏是截断数据包,首先需要设置截取数据包的类型,依次打开菜单“Rules->automatic breakpoints”,可以选择“before req ...

  8. 如何VMare虚拟机里安装Mac操作系统(图文详解)

    不多说,直接上干货! 大部分用户玩的是windows,现在,跟随我来玩玩Mac. 1. VMware Workstation 11 2. unlocker 206(for OS X 插件补丁),这是V ...

  9. 解释mysql 语句 ——解释CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

    在我们创建mysql数据库的时候我们经常会用到这句SQL:CREATE DATABASE `test` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ ...

  10. WINCRIS的使用

    附件下载:http://pan.baidu.com/s/1sj7EsOH 1.首先大家先到官网上下载自己的BIOS , 准备一个U盘格式化成FAT/FAT32格式. (网上说U盘的大小不要超过2G,这 ...