NetCore高级系列文章04---async、await原理揭秘
async、await本质上是C#提供的语法糖,编译器编译后是状态机的调用。
先看如下的一段代码,要main方法中调用了三个await方法
将此dll进行反编译为4.0的代码如下:
可见到两个Main方法,也就是说我们在程序中Main方法上加了async关键词,编译器会编译成一个是异步的一个是非异步方法,程序还是将非异步的方法作为入口函数。进入函数
在该函数中调了异步的Main方法,再进入:
在该函数中创建了一个状态机,将参数传给状态机,并调用期Start方法,可知异步方法实际上是状态机方法的调用
进入状态机类型<Main>d__0
private sealed class <Main>d__0 : IAsyncStateMachine
{
public int <>1__state; public AsyncTaskMethodBuilder <>t__builder; public string[] args; private string <text>5__1; private HttpClient <httpClient>5__2; private string <html>5__3; private string <>s__4; private string <>s__5; private TaskAwaiter<string> <>u__1; private TaskAwaiter <>u__2; private void MoveNext()
{
int num = <>1__state;
try
{
TaskAwaiter awaiter2;
TaskAwaiter<string> awaiter;
switch (num)
{
default:
<httpClient>5__2 = new HttpClient();
goto case 0;
case 0:
try
{
TaskAwaiter<string> awaiter3;
if (num != 0)
{
awaiter3 = <httpClient>5__2.GetStringAsync("https://www.baidu.com").GetAwaiter();
if (!awaiter3.IsCompleted)
{
num = (<>1__state = 0);
<>u__1 = awaiter3;
<Main>d__0 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter3, ref stateMachine);
return;
}
}
else
{
awaiter3 = <>u__1;
<>u__1 = default(TaskAwaiter<string>);
num = (<>1__state = -1);
}
<>s__4 = awaiter3.GetResult();
<html>5__3 = <>s__4;
<>s__4 = null;
Console.WriteLine(<html>5__3);
<html>5__3 = null;
}
finally
{
if (num < 0 && <httpClient>5__2 != null)
{
((IDisposable)<httpClient>5__2).Dispose();
}
}
<httpClient>5__2 = null;
awaiter2 = File.WriteAllTextAsync("E:\\test.txt", "zhengwei").GetAwaiter();
if (!awaiter2.IsCompleted)
{
num = (<>1__state = 1);
<>u__2 = awaiter2;
<Main>d__0 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter2, ref stateMachine);
return;
}
goto IL_015f;
case 1:
awaiter2 = <>u__2;
<>u__2 = default(TaskAwaiter);
num = (<>1__state = -1);
goto IL_015f;
case 2:
{
awaiter = <>u__1;
<>u__1 = default(TaskAwaiter<string>);
num = (<>1__state = -1);
break;
}
IL_015f:
awaiter2.GetResult();
Console.WriteLine("写入成功");
awaiter = File.ReadAllTextAsync("E:\\test.txt").GetAwaiter();
if (!awaiter.IsCompleted)
{
num = (<>1__state = 2);
<>u__1 = awaiter;
<Main>d__0 stateMachine = this;
<>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);
return;
}
break;
}
<>s__5 = awaiter.GetResult();
<text>5__1 = <>s__5;
<>s__5 = null;
Console.WriteLine("文件内容" + <text>5__1);
}
catch (Exception exception)
{
<>1__state = -2;
<text>5__1 = null;
<>t__builder.SetException(exception);
return;
}
<>1__state = -2;
<text>5__1 = null;
<>t__builder.SetResult();
} void IAsyncStateMachine.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
this.MoveNext();
} [DebuggerHidden]
private void SetStateMachine(IAsyncStateMachine stateMachine)
{
} void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
{
//ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
this.SetStateMachine(stateMachine);
}
}
在此状态机类中可以看到我们自己写的Main方法中的主要代码已编译到了方法MoveNext()中,并将我们的局部变量编译成了成员变量
方法中有一个case,我们自己写的三个异步方法被编译后拆到了多个case中去了,MoveNext方法会根据不同的num被多次调用
编译的代码中可见到在每次调用异步方法时都会去判断是否完成
编译后的代码意思是当执行到string html = await httpClient.GetStringAsync("https://www.baidu.com");时,如果没有完成就直接返回了,并不会再往下执行
只有当此段代码执行完成后会继续往下执行,当执行到第二个异步方法await File.WriteAllTextAsync(@"E:\test.txt","zhengwei")时又会返回,等待执行完后再往下执行
同理,执行第三步异步方法var text = await File.ReadAllTextAsync(@"E:\test.txt");也是如此
所有异步方法都 执行完成后,会break;跳出状态机。
NetCore高级系列文章04---async、await原理揭秘的更多相关文章
- 【面试题】手写async await核心原理,再也不怕面试官问我async await原理
前言 async await 语法是 ES7出现的,是基于ES6的 promise和generator实现的 generator函数 在之前我专门讲个generator的使用与原理实现,大家没了解过的 ...
- promise async await使用
1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...
- 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法
什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...
- .Net Core异步async/await探索
走进.NetCore的异步编程 - 探索 async/await 前言: 这段时间开始用.netcore做公司项目,发现前辈搭的框架通篇运用了异步编程方式,也就是async/await方式,作为一个刚 ...
- 从C#到TypeScript - async await
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- JavaScript async/await:优点、陷阱及如何使用
翻译练习 原博客地址:JavaScript async/await: The Good Part, Pitfalls and How to Use ES7中引进的async/await是对JavaSc ...
- 进阶篇:以IL为剑,直指async/await
接上篇:30分钟?不需要,轻松读懂IL,这篇主要从IL入手来理解async/await的工作原理. 先简单介绍下async/await,这是.net 4.5引入的语法糖,配合Task使用可以非常优雅的 ...
- 掌握 Async/Await
摘要: 还不用Async/Await就OUT了.. 原文:掌握 Async/Await 作者:Jartto Fundebug经授权转载,版权归原作者所有. 前端工程师肯定都经历过 JS 回调链狱的痛苦 ...
- [转帖]Java高级系列——注解(Annotations)
Java高级系列——注解(Annotations) 2018年01月13日 :: RonTech 阅读数 3405更多 所属专栏: Java高级系列文章 版权声明:转载请注明出处,谢谢配合. http ...
- js异步回调Async/Await与Promise区别 新学习使用Async/Await
Promise,我们了解到promise是ES6为解决异步回调而生,避免出现这种回调地狱,那么为何又需要Async/Await呢?你是不是和我一样对Async/Await感兴趣以及想知道如何使用,下面 ...
随机推荐
- nmcli 命令设置网络
nmcli 命令设置网络 设置静态 IP 地址 sudo nmcli connection modify "连接名称" ipv4.addresses IP地址/子网掩码 设置网关 ...
- Mysql忘记密码后如何重置密码
长时间不使用本机的Mysql后把密码忘记了咋整?直接上干货: 第一步(Mysql部署的位置,若自己能找到就忽略这一步):任务管理器中也可以找到 第二步:修改配置文件 在my.ini末尾加上 skip- ...
- strimzi实战之二:部署和消息功能初体验
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇是<strimzi实战>系列 ...
- CF 下分记录
7.27 edu152 \(+173=2048\) B 没细看数据范围 WA 了一次 D 没判 \(i-1=0\) WA 了一次 E. Max to the Right of Min 考虑增大右端点, ...
- Go字符串实战操作大全!
在本篇文章中,我们深入探讨了Go语言中字符串的魅力和深度.从基础定义.操作.字符编码到复杂的类型转换,每个环节都带有实例和代码示例来深化理解.通过这些深入的解析,读者不仅能够掌握字符串在Go中的核心概 ...
- Java 位运算的解读 & | ^ ~ << >>
Java中的位运算包括以下几种: 按位与(&):对应位上,如果两个数都是1,则结果为1,否则为0. int a = 3; // 二进制 0011 int b = 5; // 二进制 0101 ...
- day1 C语言:对于P1055 ISBN号码的代码优化及多解
day1 C语言:对于P1055 ISBN号码的代码优化及多解 先看题目 直接说最优解,其他方法后置 第一部分 1.第一个点是数据的输入,本人第一的想法是直接用int类型去接受数据,但因为" ...
- 拒绝恶意IP登录服务器
拒绝恶意IP登录服务器,并加入防火墙黑名单 #!/bin/bash #2020-03-20 16:39 #auto refuse ip dlu #By Precious ############### ...
- C++快读、快写模版
inline int read() { char ch = getchar(); int x = 0,f = 1; while (!isdigit(ch)) if (ch == '-') f = -1 ...
- Python JSON 使用指南:解析和转换数据
JSON 是一种用于存储和交换数据的语法.JSON 是文本,使用 JavaScript 对象表示法编写. Python 中的 JSON Python 有一个内置的 json 包,可用于处理 JSON ...