C#里的async和await

C# vNext为了将异步变得更为简单,引入了2个关键字,asyncawait,下面简单介绍下这2个关键字给我们的编程带来怎么样的改变。

以一个标准的逻辑为例:下载一个远程URI,并将内容输出在界面上,假设我们已经有了显示内容的方法:

void Display(string text)
{
// 不管是怎么实现的
}

如果用标准的同步式写法,这代码相当之容易:

void ShowUriContent(string uri)
{
using (WebClient client = new WebClient())
{
string text = client.DownloadString(uri);
Display(text);
}
}


当然这不是我们讨论的重点,同步方式会造成线程的阻塞,必须选择WebClient下载完成才可以继续运行,如果这个过程在UI线程上执行,则会造成UI无响应的情况。同时网络是非常不可预测的外部条件,很可能因为网络状况不好导致程序长时间没有响应,显然不是我们希望得到的结果。

所以我们又有了异步的方案,.NET中最早的异常编程模式是Begin/End模式,不过WebClient作为WebRequest的高层封装,已经把这个模式给封装了:

void DownloadUri(string uri)
{
using (WebClient client = new WebClient())
{
client.DownloadStringCompleted +=new DownloadStringCompletedEventHandler(ShowContent);
client.DownloadStringAsync(uri);
}
}
 
void ShowContent(object sender, DownloadStringCompletedEventArgs e)
{
Display(e.Result);
}


看看,好好的事情一变成异步,就变得麻烦无比。一个很明确逻辑的方法活生生拆成2个来处理,虽然可以用Lambda或者delegate来使代码上 进行简化,但依旧无可避免一段逻辑被拆成两段的痛苦。当更多的异步操作交叉在一起的时候,无论是代码的组织还是逻辑的梳理都会变得更加麻烦。

正因为如此,C# vNext引入了关键了,从语法上对此进行了改进,当使用asyncawait时,我们的代码会变成这样:

void async ShowUriContent(string uri)
{
using (WebClient client = new WebClient())
{
string text = await client.DownloadStringTaskAsync(uri);
Display(text);
}
}


悄悄地告诉你,我写上面这段代码的时候,是直接把同步方案的代码复制过来再稍微发了几个字符的……由此可见,在语言级别给予支持后,代码的编写将会是如何地顺畅和简便。这段代码看上去就是一段典型的同步逻辑,创建-下载-显示按部就班,唯一不同地就是在方法声明中加入了async关键字,在DownloadStringTaskAsync方法的调用时加入了await关键字。就这么神奇地,运行时变成了异步。ShowUriContent方法会在调用DownloadStringTaskAsync后退出,而下载过程会异步进行,当下载完成后,再进入Display方法的执行,期间不会阻塞线程,不会造成UI无响应的情况。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值