转载自 http://www.jb51.net/article/53399.htm

这篇文章主要介绍了关于async和await的一些误区实例详解,有助于更加深入的理解C#程序设计,需要的朋友可以参考下

微软官方的MSDN上说async和await是“异步”,但是不少人(包括笔者自己)都有一些误区需要澄清:为什么await语句之后没有执行?不是异步吗?

先举一个示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public partial class Form1 : Form
{
 public async Task Processing()
 {
   await Task.Delay(5000);
   label1.Text = "Succuessful";
 }
 public Form1()
 {
   InitializeComponent();
    
 }
 private async void button1_Click(object sender, EventArgs e)
 {
   await Processing();
   MessageBox.Show("Button's event completed");
 }
}

很多人(包括笔者)一开始会觉得异步好像类似多线程一样,到await的时候会在后台先开启一个线程执行任务,随后主线程(这里是UI线程)将自动执行后面的部分(即弹出“Button's event completed”的消息框)。

其实这个理解是错误的。async和await的本质其实是“yield return”和“LINQ”的“迭代式”等待。我们应该清楚一点:那就是你写了LINQ语句:

1
2
3
4
5
6
7
var results = from ……
       select ……;
 
foreach(var r in results)
{
 ……
}

当你下断点你会发觉results并不会立即执行,直到使用到results的地方(例子中也就是foreach这里)才会被执行(此时黄色跟踪调试的光棒又会折回到var results……这里,然后等到results执行完毕之后才真正进入foreach进行执行)。

所以,async/await和LINQ的这种“迭代式”的“异步操作”是异曲同工的。只不过async/await本质是返回一个Task而已,而Task又是异步的(因为Task本质就是一个线程),所以真正执行到(使用到async方法的时候)带有await的方法的时候,后台才会真正开启一个线程去执行任务。此时主线程会等待这个Task线程直到其执行完毕(IsComplete属性为True为止)。所以界面是不会卡顿的。

所以,await是Task的异步等待而已,并不是我们所谓的“异步操作”;拿它和LINQ作对比,你会发现LINQ执行顺序和它一致,只不过LINQ没有异步等待(当然没有!又没有开启线程啥的……)。

我们进一步可以这样对比:

LINQ:变量 = LINQ语句(表达式)

等到使用LINQ变量的时候才折返到LINQ语句处真正执行LINQ语句。

异步等待:变量 = 异步方法

等到使用await+异步方法的时候才会折返到该异步方法处,开启线程真正执行异步方法,主线程被挂起(但不会造成界面死掉),直至子线程Task任务完全执行完毕为止。

在LINQ中,你如果需要立即执行,可以使用扩展方法:

var results = (from ……
              select ……).ToList();
因为立即使用到了这个LINQ语句,所以会被立即执行。

同样地,异步等待也可以变成类似Wait一样的同步等待:

1
2
3
4
5
private async void button1_Click(object sender, EventArgs e)
{
  Processing().GetAwaiter().GetResult();
  MessageBox.Show("Button's event completed");
}

因为Processing本来就返回Task,当然也可以使用Wait进行同步等待。

关于async和await的一些误区实例详解的更多相关文章

  1. linux基础-磁盘阵列(RAID)实例详解

    磁盘阵列(RAID)实例详解 raid技术分类 软raid技术 硬raid技术 Raid和lvm的区别 为什么选择用raid RAID详解 RAID-0 RAID-1 RAID-5 Raid-10 R ...

  2. Cocos2d-x 3.X手游开发实例详解

    Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰 ...

  3. JavaScript学习笔记-实例详解-类(二)

    实例详解-类(二)   //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...

  4. JavaScript学习笔记-实例详解-类(一)

    实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...

  5. Entity Framework实例详解

    Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...

  6. 免费的HTML5连载来了《HTML5网页开发实例详解》连载(二)

    最近新浪.百度.腾讯.京东.大众点评.淘宝等流行的网站都加大了招聘HTML5的力度,HTML5开发人员成了抢手货,本次连载的是由大众点评前端工程师和一淘网前端工程师基情奉献的<HTML5网页开发 ...

  7. Linux下rz命令使用的实例详解

    Linux中rz命令和sz命令都可用于文件传输,而rz命令主要用于文件的上传,下面将通过几个实例来给大家详细介绍下Linux下rz命令的用法,一起来学习下吧. rz命令可以批量上传文件,当然也可上传单 ...

  8. 实例详解 DB2 排序监控和调优

    实例详解 DB2 排序监控和调优http://automationqa.com/forum.php?mod=viewthread&tid=2882&fromuid=2

  9. 转:【工欲善其事必先利其器】—Entity Framework实例详解

    开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/ ...

随机推荐

  1. STL(pair map set vector priority_queue) poj 3297

    POJ 3297 算法竞赛初级杂烩包 题意:学生选课,没个学生只能选一门课.大写字符是课的名字,小写是人名.如果课程后面有多个相同名字算一个,如果一个人选多门课,则他选不上课,输出课和每门课选课人数 ...

  2. HW7.10

    public class Solution { public static void main(String[] args) { int[][] array = new int[3][3]; for( ...

  3. 【noip2007】树网的核

    题解: 首先我们要知道一个性质:如果有多条直径 这个核不论在哪条直径上 答案都是一样的 这样我们就可以随便找一条直径 在这条直径上枚举核的位置 并且dfs预处理maxlon[i] (i在直径上) 表示 ...

  4. BNUOJ-26474 Bread Sorting 逆序对

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=26474 题意:给一个数列,可以对三个数操作:把最后一个数放到第一个,前两个数后移一位.问最 ...

  5. [POLITICS] S Korea lawmakers vote to impeach leader

    South Korea's Parliament has voted to impeach President Park Geun-hye. The National Assembly motion ...

  6. 常用 Unicode 符号列表

    Unicode 中包含了各种符号,我们可以作为图标来使用.这里整理一下常用的一些符号. 一.拉丁字母补全(Latin-1 Supplement):U+0080 至 U+00FF Unicode 编号 ...

  7. hadoop 2.0 详细配置教程

    http://www.cnblogs.com/scotoma/archive/2012/09/18/2689902.html

  8. 安卓开发21:深入理解Handler

    Handler相关说明: 主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 解释:安卓的UI线程(即OnCreate函数创建的线程)是线程非安全的.也就是说,在UI线程中,使用sleep这样 ...

  9. 08重编终极版《东邪西毒:终极版》DVD粤语中字

    1.东邪西毒].Ashes.of.Time.1994.384p.DVDRip.x264.ac3-DTMM.mkv 这个版本最清晰 ,可惜删减了,只有87分钟,粤语,1.4G. 2.东邪西毒(初始版). ...

  10. javafx for android or ios ?

    javafx是否支持android 或者 ios这是一个令人感兴趣的话题.google一番,发现有可行方案: 1. javafx on android: 两种方案:(事实上差点儿相同) 1.有位大神已 ...