C# vNext为了将异步变得更为简单,引入了2个关键字,async和await,下面简单介绍下这2个关键字给我们的编程带来怎么样的改变。
以一个标准的逻辑为例:下载一个远程URI,并将内容输出在界面上,假设我们已经有了显示内容的方法:
如果用标准的同步式写法,这代码相当之容易:
当然这不是我们讨论的重点,同步方式会造成线程的阻塞,必须选择WebClient下载完成才可以继续运行,如果这个过程在UI线程上执行,则会造成UI无响应的情况。同时网络是非常不可预测的外部条件,很可能因为网络状况不好导致程序长时间没有响应,显然不是我们希望得到的结果。
所以我们又有了异步的方案,.NET中最早的异常编程模式是Begin/End模式,不过WebClient作为WebRequest的高层封装,已经把这个模式给封装了:
看看,好好的事情一变成异步,就变得麻烦无比。一个很明确逻辑的方法活生生拆成2个来处理,虽然可以用Lambda或者delegate来使代码上 进行简化,但依旧无可避免一段逻辑被拆成两段的痛苦。当更多的异步操作交叉在一起的时候,无论是代码的组织还是逻辑的梳理都会变得更加麻烦。
正因为如此,C# vNext引入了关键了,从语法上对此进行了改进,当使用async和await时,我们的代码会变成这样:
悄悄地告诉你,我写上面这段代码的时候,是直接把同步方案的代码复制过来再稍微发了几个字符的……由此可见,在语言级别给予支持后,代码的编写将会是如何地顺畅和简便。这段代码看上去就是一段典型的同步逻辑,创建-下载-显示按部就班,唯一不同地就是在方法声明中加入了async关键字,在DownloadStringTaskAsync方法的调用时加入了await关键字。就这么神奇地,运行时变成了异步。ShowUriContent方法会在调用DownloadStringTaskAsync后退出,而下载过程会异步进行,当下载完成后,再进入Display方法的执行,期间不会阻塞线程,不会造成UI无响应的情况。