async&await=custom IAsyncStateMachine
async&await是IAsyncStateMachine的语法糖

验证

分别使用async&await和IAsyncStateMachine遍历一棵树,查看二者的线程id和线程上下文标识是否相同

数据结构

public class Node
{private static List<Node> _nodes = new List<Node>(); private static int _id = 1; public Node() { this.Id = _id++; _nodes.Add(this); } public int Id { get; } public Node Left { get; set; } public Node Right { get; set; } public bool IsLeaf => this.Left == null && this.Right == null; public bool IsTraveled { get; set; } = false; public override string ToString() { return $"{Left?.Id ?? 0}|{this.Id}|{Right?.Id ?? 0}"; } }

使用async&await遍历树

public static async Task<int> Travle(Node node) { node.IsTraveled = true; if (!node.IsLeaf) { Console.WriteLine("线程id:" + Thread.CurrentThread.ManagedThreadId + "|线程上下文标识:" + Thread.CurrentThread.ExecutionContext.GetHashCode() + ":" + await Travle(node.Left)); Console.WriteLine("线程id:" + Thread.CurrentThread.ManagedThreadId + "|线程上下文标识:" + Thread.CurrentThread.ExecutionContext.GetHashCode() + ":" + await Travle(node.Right)); } return node.Id; }

使用IAsyncStateMachine遍历树

public static Task<int> StateMechineTravle(Node node) { StateMechine stateMechine = new StateMechine(); stateMechine.node = node; stateMechine.builder = AsyncTaskMethodBuilder<int>.Create(); stateMechine.state = -1; AsyncTaskMethodBuilder<int> next_builder = stateMechine.builder; next_builder.Start<StateMechine>(ref stateMechine); return stateMechine.builder.Task; }

这里StateMechine是实现IAsyncStateMachine接口的一个类

public struct StateMechine : IAsyncStateMachine
{public int state; public AsyncTaskMethodBuilder<int> builder; public Node node; private object wrap1; private object wrap2; private TaskAwaiter<int> awaiter; void IAsyncStateMachine.MoveNext() { int num = this.state; int id; try { TaskAwaiter<int> taskAwaiter; if (num != 0) { if (num == 1) { taskAwaiter = this.awaiter; this.awaiter = default(TaskAwaiter<int>); this.state = -1; goto IL_1AB; } this.node.IsTraveled = true; if (this.node.IsLeaf) { goto IL_20C; } this.wrap1 = Thread.CurrentThread.ManagedThreadId; this.wrap2 = Thread.CurrentThread.ExecutionContext.GetHashCode(); taskAwaiter = Program.StateMechineTravle(this.node.Left).GetAwaiter(); if (!taskAwaiter.IsCompleted) { this.state = 0; this.awaiter = taskAwaiter; this.builder.AwaitUnsafeOnCompleted<TaskAwaiter<int>, StateMechine>(ref taskAwaiter, ref this); return; } } else { taskAwaiter = this.awaiter; this.awaiter = default(TaskAwaiter<int>); this.state = -1; } int arg_CC_0 = taskAwaiter.GetResult(); taskAwaiter = default(TaskAwaiter<int>); object obj = arg_CC_0; Console.WriteLine(string.Concat(new object[] { "线程id:", this.wrap1, "|线程上下文标识:", this.wrap2, ":", obj })); this.wrap1 = null; this.wrap2 = null; this.wrap2 = Thread.CurrentThread.ManagedThreadId; this.wrap1 = Thread.CurrentThread.ExecutionContext.GetHashCode(); taskAwaiter = Program.StateMechineTravle(this.node.Right).GetAwaiter(); if (!taskAwaiter.IsCompleted) { this.state = 1; this.awaiter = taskAwaiter; this.builder.AwaitUnsafeOnCompleted<TaskAwaiter<int>, StateMechine>(ref taskAwaiter, ref this); return; } IL_1AB: int arg_1BA_0 = taskAwaiter.GetResult(); taskAwaiter = default(TaskAwaiter<int>); obj = arg_1BA_0; Console.WriteLine(string.Concat(new object[] { "线程id:", this.wrap2, "|线程上下文标识:", this.wrap1, ":", obj })); this.wrap2 = null; this.wrap1 = null; IL_20C: id = this.node.Id; } catch (Exception exception) { this.state = -2; this.builder.SetException(exception); return; } this.state = -2; this.builder.SetResult(id); } [DebuggerHidden] void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { this.builder.SetStateMachine(stateMachine); } }

结果

输入1,使用async&await遍历树
输入2,使用IAsyncStateMachine遍历树
可以看出,二者一毛一样

可见,基于async和await的task不会被多线程调用

示例代码

https://github.com/snys98/AsyncStateMechineTest

官方资料

https://docs.microsoft.com/zh-cn/dotnet/api/system.runtime.compilerservices.iasyncstatemachine?view=netframework-4.7.1

转载于:https://www.cnblogs.com/Microex/p/8360457.html

asyncawait的前世今生相关推荐

  1. 【云栖大会精华汇】历届云栖大会精彩资料大放送,一篇看尽云栖大会前世今生...

    [热点头条] 历届云栖大会精彩资料大放送,一篇看尽云栖大会前世今生        如果从2009-2010年算起,2017杭州云栖大会已经是第八届.为帮助更多朋友认识云栖大会,云栖社区特别整理了历届云 ...

  2. 从芯片到AI智能芯片,一文了解它的前世今生

    作者 | 元宵大师,Python高级工程师,致力于推动人工智能.大数据分析在金融量化交易领域中的应用.欢迎大家关注我的个人公众号<元宵大师带你用Python量化交易>. 责编 | 胡巍巍 ...

  3. 追溯XLNet的前世今生:从Transformer到XLNet

    作者丨李格映 来源 | 转载自CSDN博客 导读:2019 年 6 月,CMU 与谷歌大脑提出全新 XLNet,基于 BERT 的优缺点,XLNet 提出一种泛化自回归预训练方法,在 20 个任务上超 ...

  4. Transformer不比CNN强!Local Attention和动态Depth-wise卷积的前世今生

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者丨Qi Han@知乎(已授权) 来源丨https://zhuan ...

  5. 图像配准的前世今生:从人工设计特征到深度学习

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 机器之心编译 参与:Nurhachu Null,Geek AI 作 ...

  6. 基于GAN模型的生成人脸重构、返老还童、看见前世今生(Age Progression/Regression)

    基于GAN模型的生成人脸重构.返老还童.看见前世今生(Age Progression/Regression) 看见前世今生(Age Progression/Regression) GAN的优势是直接可 ...

  7. Atitit 图像处理类库安装与安装模式的前世今生与未来大趋势attilax总结.docx

    Atitit 图像处理类库安装与安装模式的前世今生与未来大趋势attilax总结.docx 1. 安装的原理,主要是解压,复制,设置三大步1 2. 目前我们常见的三大种安装模式,二进制模式与源码安装模 ...

  8. 对话文津|相约“信息”的前世今生

    你知道什么是信息吗? 你知道信息的过去与 未来究竟是怎样的吗? 恐怕荣获第九届文津图书奖的<信息简史> 会给你最好的答案. 一部<信息简史>, 相当于一整部人类文明的发展史. ...

  9. 学术报告 | 数据库专家C.Mohan ——人工智能的前世今生

    清华大学软件学院杰出访问教授C.Mohan为您讲解人工智能的前世今生.

  10. 知识图谱的皇冠:知识图谱推理的前世今生

    作者:费斌杰 本文约4200字,建议阅读8分钟 本文聚焦于知识推理的理论研究和产业实践,剖析知识图谱推理的前世今生以及最近研究进展,以飨读者. [ 导读 ]业界和学界对知识图谱的关注主要集中于两大领域 ...

最新文章

  1. JavaScript对象数组示例
  2. Day 02 你最爱的交通方式
  3. 职工信息管理软件c语言大一,职工信息管理(C语言
  4. 2009中国海上大阅兵全视频
  5. nginx指定配置文件启动_NGINX安全加固手册
  6. 容器 | Docker 如此之好,你为什么还要用k8s
  7. laravel 路由模型绑定
  8. apache php提示下载,apache正在下载php文件而不是显示它们。
  9. poj 匈牙利二分匹配算法2239 Selecting Courses
  10. laravel validate
  11. Atitit 导航模式 面包屑 胶囊式 标签式tab 目录 1.1. 表格导航 1 2. 面包屑导航来源于童话故事中的汉塞尔利用面包屑来记录回家的路的故事 1 2.1.1. 格林童话《Hanse
  12. ubuntu 导入mysql_Ubuntu16.04系统mysql命令导入导出sql文件
  13. python移动文件到新的文件夹并重命名
  14. VS下更新Qt语言家ts文件没反应
  15. oracle11g64跟32,plsql32 位连接oracle11g64位方法
  16. java学习之类方法
  17. 英华特在创业板提交注册:拟募资约5亿元,股权结构较为分散
  18. 【顺丰一面】2020/4/5_顺丰第一次技术面试_20分钟
  19. 基于数据挖掘的上市公司财务数据分析——第九届“泰迪杯”挑战赛A题优秀作品
  20. Friedman 检验--Matlab

热门文章

  1. Unity ML-Agents 之 平衡球案例的实现整理(内含实现步骤)
  2. 【优化求解】基于天牛须算法PID控制器优化设计matlab代码
  3. 红米8.0系统手机(亲测有效)激活xposed框架的经验
  4. 关于cad生成dwf文件和插入dwf快
  5. 建立量化交易趋势跟踪策略的五个指标
  6. 看完就学会系列,小小一篇文章教会你利用Python网络爬虫抓取王者荣耀图片(建议收藏)
  7. 33、什么是 AIO?
  8. 洛谷P1308统计单词数Java题解
  9. 用Matlab的FDAtool生成IIR滤波器参数
  10. android使用新浪邮箱,新浪邮箱