还在吗?我们开始吧。由于深入讲解需上百页的篇幅,因此这里我不会讲得太深。但我会提 供足够的背景知识,以有助于你对整个结构的理解。之后可通过阅读我近些年来撰写的博客文章, 来了解更加错综复杂的细节,或简单地编写一些异步代码并反编译。同样地,这里我只介绍异步 方法,它包含了所有有趣的机制,并且不需要处理异步匿名函数所处的间接层。

  说明 警告,勇敢的旅行者—— 前方是实现细节! 本节将描述微软C# 5编译器(随着.NET 4.5的发布而推出)内实现的相关内容。从CTP版到beta版,有些细节变化很大,并且在未 来仍有可能发生改变。但我认为其基本理念并不会发生太大的变动。充分了解本节内容 后,你会发现并不存在什么魔法,只不过是一些编译器生成的聪明代码罢了。这之后便 可以从容应对未来变化的细节内容了。 正如我之前多次提到过的,它的实现(包括近似实现和真实编译器生成的代码)基本上可以 说是一个状态机。编译器将生成一个私有的内嵌结构,来表示这个异步方法。这个结构还必须包 含一个方法,其签名与所声明的方法签名相同。我称其为骨架方法,该方法本身没有多少内容, 但其他东西都依赖于它。

  骨架方法需要创建状态机,并执行一个步骤(此处的步骤指执行第一个 await 表达式之前的 代码),然后返回一个表示状态机进度的任务。(别忘了,在第一次到达真正需要等待的 await 表 达式之前,执行过程是同步的。)此后,骨架方法的运作就此结束。状态机会负责其余事项,后 续操作附加到其他异步操作后,可通知状态机去执行另一个步骤。当之前返回的任务被赋予适当 的值后,方法就执行到最后了, 状态机可随即发出信号。

  当然,“执行方法体中的代码”这一步,只有在骨架方法中第一次调用时,才会从方法的开 头执行。以后每次到达该块,都是由后续操作从之前中断的地方开始继续执行。 现在有两个概念需要关注,即骨架方法和状态机。在本节的剩余篇幅中,我将使用单个异步 方法作为示例,如代码清单15-11所示。

         static async Task<int> SumCharactersAsync(IEnumerable<char> text)
{
int total = ;
foreach (char ch in text)
{
int unicpde = ch;
await Task.Delay(unicpde);
total += unicpde;
}
await Task.Yield();
return total;
}

代码清单15-11没有什么实际意义,但我们只关注流控制。在开始之前,有必要指出以下几点。
 该方法包含一个参数( text )。
 该方法包含一个循环,后续操作执行时需跳回该循环内。
 该方法包含两个不同类型的 await 表达式: Task.Delay 返回一个 Task ,而 Task.Yield()则返回一个 YieldAwaitable 。
 该方法包含显式的局部变量( total 、 ch 和 unicode ),需在不同的调用间关注其变化。
 该方法包含一个通过调用 text.GetEnumerator() 方法创建的隐式局部变量。
 该方法最终返回一个值。
这段代码最初的版本将 text 作为 string 类型的参数,但C#编译器会对字符串的迭代进行优
化,并使用 Length 属性和索引器,这会使反编译后的代码变得更加复杂。

15.5.1【Task实现细节】 生成的代码的更多相关文章

  1. 15.5.5 【Task实现细节】围绕 await 表达式的控制

    任何 await 表达式均表示执行路径的一个分支.首先,被等待的异步操作得到一个awaiter,然后检查其 IsCompleted 属性.若返回 true ,即可立即获得结果并继续.否则,需进行以下处 ...

  2. MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    前言 经过前面EF的<第一篇>与<第二篇>,我们的数据层功能已经较为完善了,但有不少代码相似度较高,比如负责实体映射的 EntityConfiguration,负责仓储操作的I ...

  3. [转]MVC实用架构设计(三)——EF-Code First(3):使用T4模板生成相似代码

    本文转自:http://www.cnblogs.com/guomingfeng/p/mvc-ef-t4.html 〇.目录 一.前言 二.工具准备 三.T4代码生成预热 (一) 单文件生成:Hello ...

  4. .net postsharp编译时生成的代码?

    使用PostSharp进行AOP框架设计:一个简单的原型   AOP已经不是一个什么新名词了,在博客园使用关键字搜索可以查出n多条关于AOP的介绍,这里就不再赘述了. 在Bruce Zhang's B ...

  5. 使用xorm工具,根据数据库自动生成 go 代码

    使用xorm工具,根据数据库自动生成 go 代码 引入 使用 golang 操作数据库的同学都会遇到一个问题 -- 根据数据表结构创建对应的 struct 模型.因为 golang 的使用首字母控制可 ...

  6. .NetCore2.1 WebAPI 根据swagger.json自动生成客户端代码

    前言 上一篇博客中我们可以得知通过Swagger插件可以很方便的提供给接口开发者在线调试,但是实际上Swagger附带的功能还有很多, 比如使用NSwag生成客户端调用代码,进一步解放接口开发者. N ...

  7. 使用Emmet 快速生成HTML代码

    在前端开发的过程中,一个最繁琐的工作就是写 HTML.CSS 代码.数量繁多的标签.属性.尖括号.标签闭合等,让前端们甚是苦恼.于是,我向大家推荐 Emmet,它提供了一套非常简单的语法规则,书写起来 ...

  8. STM32F103C8T6-CubeMx串口收发程序详细设计与测试(1)——CubeMx生成初始代码

    STM32F103C8T6-CubeMx串口收发程序详细设计与测试(1)--CubeMx生成初始代码 关键词:STM32F103C8T6 CubeMX UART 详细程序设计 1.开发环境 (1)ST ...

  9. MySQL建表语句生成Golang代码

    1. 背景 对于后台开发新的需求时,一般会先进行各种表的设计,写各个表的建表语句 然后根据建立的表,写对应的model代码.基础的增删改查代码(基础的增删改查服务可以划入DAO(Data Access ...

随机推荐

  1. MYSQL 源码

    http://www.cnblogs.com/wingsless/tag/MySQL/

  2. optimizer_index_cost_adj

    Oracle在选择不同的访问路径时,会对全表扫描和索引扫描进行比较评估. 在比较的时候,Oracle会把索引扫描的成本转换为全表扫描的成本,和全表扫描的COST进行比较.这个转换需要一个转换因子. 就 ...

  3. android studio配置android开发环境

    1.下载安装android-studio-bundle 地址:https://developer.android.com/sdk/index.html 注意:指定android sdk和android ...

  4. java面向接口编程

    在oop中有一种设计原则是面向接口编程,面向接口编程有非常多优点,详细百度一大片.我来谈一下详细的使用中的一些不成熟的见解.! 首先面向接口编程能够消除类之间的依赖关系,使得业务仅仅依赖接口. 这样有 ...

  5. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  6. 关于QT版本的安装配置的一些困惑

    大概是之前安装和使用QT太顺利了,什么都没注意就开始使用了.在使用VS2012开发Qt5.31的程序一段时间以后,虽然好用,但是发现其编译的程序不能在XP上使用,要打补丁才行.不仅VS2012本身要打 ...

  7. Ubuntu17.10 下配置caffe 仅CPU i386可以直接apt install caffe-cpu,但是怎么运行mnist代码我懵逼了

    Ubuntu16.04下配置caffe(仅CPU)  参考:http://blog.csdn.net/zt_1995/article/details/56283249   第二次配置caffe环境,依 ...

  8. Codeforces--630K--Indivisibility(容斥)

     K - Indivisibility Crawling in process... Crawling failed Time Limit:500MS     Memory Limit:65536 ...

  9. RTP协议分析和详解

    一.RTP协议分析 第1章.     RTP概述 1.1.  RTP是什么 RTP全名是Real-time Transport Protocol(实时传输协议).它是IETF提出的一个标准,对应的RF ...

  10. angular的directive指令的link方法

    比如 指令标签 <mylink myLoad="try()"></mylink> link:function(scope,element,attr){ el ...