原理
与同步函数相比,CLR在执行异步函数时有几个不同的特点:
1. 并非一次完成,而且分多次完成
2. 并非由同一个线程完成,而是线程池每次动态分配一个线程来处理;
结合这些特点,C#编译器将异步函数转换为一个状态机结构。这种结构能挂起和恢复。它的执行方式是一种工作流的方式。
执行步骤
1. CLR创建一个状态机,这个状态机的操作数默认值为-1。
2. 开始执行状态机
3. 状态机通过操作数来选定执行路径
4. 状态机调用GetAwaiter方法来获取一个等待者对象awaiter,它的类型为TaskAwaiter<T>
5. 状态机获取awaiter后,查询其IsCompleted属性。
6. 若IsCompleted为True,则操作已经以同步方式完成,状态机继续执行以处理结果。
7. 若IsCompleted为False,则操作将以异步方式来完成,状态机调用awaiter的OnCompleted方法并向它传递一个委托(引用状态机的MoveNext来实现工作流状态的变迁)。这时状态机允许线程返回原地以执行其它代码。
8. 将来某个时候,awaiter会在完成时调用委托以执行MoveNext,这时可根据状态机中的字段知道如何到达代码中的正确位置,使方法能够从它当初离开的位置继续。
9. 调用awaiter的GetResult方法获取结果,并进行处理。
10. 状态机执行完毕后,垃圾回收器会回收任何内存。
限制
1. 应用程序的Main方法不能转变成异步函数
2. 构造函数、属性、事件不能转变成异步函数
3. 不能在catch、finally、unsafe块中使用await操作符
4. 不能在支持线程锁中使用await操作符
5. Linq中,只能在from子句的第一个集合表达式或join子句的集合表达式中使用await操作符。
C# Async/Await异步函数原理的更多相关文章
-
async/await 异步编程(转载)
转载地址:http://www.cnblogs.com/teroy/p/4015461.html 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入 ...
-
async/await 异步编程
前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关的知识,并整理成这篇博客,如果在 ...
-
.NET 中的 async/await 异步编程
原文出处: Teroy 的博客 前言 最近在学习Web Api框架的时候接触到了async/await,这个特性是.NET 4.5引入的,由于之前对于异步编程不是很了解,所以花费了一些时间学习一下相关 ...
-
将 async/await 异步代码转换为安全的不会死锁的同步代码
在 async/await 异步模型(即 TAP Task-based Asynchronous Pattern)出现以前,有大量的同步代码存在于代码库中,以至于这些代码全部迁移到 async/awa ...
-
C#中 Thread,Task,Async/Await 异步编程
什么是异步 同步和异步主要用于修饰方法.当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法:当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调 ...
-
async/await异步处理demo
async/await异步处理demo 下载地址: async/await异步处理demo
-
【转】C# Async/Await 异步编程中的最佳做法
Async/Await 异步编程中的最佳做法 Stephen Cleary 近日来,涌现了许多关于 Microsoft .NET Framework 4.5 中新增了对 async 和 await 支 ...
-
深入理解协程(四):async/await异步爬虫实战
本文目录: 同步方式爬取博客标题 async/await异步爬取博客标题 本片为深入理解协程系列文章的补充. 你将会在从本文中了解到:async/await如何运用的实际的爬虫中. 案例 从CSDN上 ...
-
.NET Web应用中为什么要使用async/await异步编程
前言 什么是async/await? await和async是.NET Framework4.5框架.C#5.0语法里面出现的技术,目的是用于简化异步编程模型. async和await的关系? asy ...
随机推荐
-
Ubuntu学习总结-08 Ubuntu运行Shell脚本报 shell /bin/bash^M: bad interpreter错误问题解决
错误原因之一很有可能是运行的脚本文件是DOS格式的, 即每一行的行尾以\r\n来标识, 其ASCII码分别是0x0D, 0x0A.可以有很多种办法看这个文件是DOS格式的还是UNIX格式的, 还是MA ...
-
jQuery validate 验证隐藏域
$.validator.setDefaults({ ignore: '' }); 不要加载jQuery ready中,什么改写changelog ,那是扯蛋
-
java:异常处理
异常:编译正常,但运行出错,会中断正常指令流 RuntimeException:运行时异常 分为:uncheck exception.和check exception(除了RuntimeExcepti ...
-
(转) ThinkPHP模板自定义标签使用方法
这篇文章主要介绍了ThinkPHP模板自定义标签使用方法,需要的朋友可以参考下 转之--http://www.jb51.net/article/51584.htm 使用模板标签可以让网站前台开发 ...
-
Docker简单介绍
Docker简单介绍 Docker是一个能够把开发的应用程序非常方便地部署到容器的开源引擎.由Docker公司团队编写,基于Apache 2.0开源授权协议发行.Docker的主要目的例如以下: 提供 ...
-
java.io.FileNotFoundException: ..\lib\commons-el.jar
安装openfire成功后,启动遇到java.io.FileNotFoundException: ..\lib\commons-el.jar错误,并不是缺少了jar包,只需以管理员身份运行即可解决.
-
学JAVA第十六 天,JAVA多态
今天老师讲了多态的使用 多态是同一个行为具有多个不同表现形式或形态的能力. 多态的优点: 1. 消除类型之间的耦合关系 2. 可替换性 3. 可扩充性 4. 接口性 5. 灵活性 6. 简化性 我个 ...
-
ubuntu 下安装mulval
怎么在虚拟机下安装ubuntu这里就不多说了 ubuntu怎么安装静态ip可以参考:https://www.cnblogs.com/braveym/p/8640563.html ubuntu安装jdk ...
-
nginx 获取自定义header头部信息
为了排查线上的bug,需要在nginx的日志中,打印客户端上传上来的header头部信息,同时头部信息是自定义的.在尝试多重方案后,找到解决方法: log_format dm '"$remo ...
-
[USACO17FEB]Why Did the Cow Cross the Road III P(CDQ分治)
题意 两列$n$的排列,相同的数连边,如果一对数有交叉且差的绝对值$>k$,则$++ans$,求$ans$ 题解 可以把每一个数字看成一个三元组$(x,y,z)$,其中$x$表示在第一列的位置, ...