await/asyncC#5.0 引入的语法糖
语法糖:由编译器提供的便捷功能,为开发带来便捷 C#的语法糖真是非常多的 var async await
1.async 是用来修饰方法,如果单独出现,方法会警告,没有什么作用
2 .await 在方法体内部,只能放在async修饰的方法内,必须放在task前面 (真的吗?)
3 .加了await之后,await之后的内容,会等到Task全部完成之后才执行---但是线程没有阻塞,回去干自己的活儿;然后await里面的内容由新线程A 完成,且后续内容也由新的线程B完成(A和B可以相同,也可能不同)
4. async/await方法里面如果没有返回值,推荐返回一个Task,或者void(推 荐用Task,而不是void,因为这样才能await/wait)
5. 带async+await后,返回值要多一层
Task Await可以用同步的方式写异步
返回值问题,耿耿于怀---其实因为看到的不是真相,实际上方法变成了 MoveNext()---所以返回值也就释然了
1 await/async并发吗—没有并发(单个方法),提升性能吗---不能,性能低于同步调用---用了 await,对单个方法,单次处理,是没有性能提升的
2 意义何在? A 用同步的方式写异步,不会阻塞线程,提升用户体验 B 在于多请求并发处理,且资源有限的时候,能增加吞吐量(单位时间处理的请求)
Eleven的小孩3岁---正餐喂饭---需要花Eleven1个小时—就算自己吃,我也只能等着 他也在读托班---3个老师12个孩子---负责喂饭---得4个小时---实际情况是孩子们一起开饭,先自己 吃,等着不吃了等着喂,才去喂---才花1.5小时---实际情况:一开始喂3个孩子,然后他们自己吃, 然后再去喂别的孩子,3个老师没闲着,但是不是全程喂,需要孩子自己也能吃一会(3个线程推 动12个事儿同时执行,有部分事儿不需要老师一直参与,单个孩子还是1小时,但是吞吐上去了)
1 空的Async方法 2 Async/await是语法糖---生成了IAsyncStateMachine异步状态机 3 AsyncTaskMethodBuilder建造者去组装的Async方法 状态机模式:一个对象根据不同的状态会有不同的行为(对象只有一 个,类似红绿灯) <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine);----新的状态机,状态=0,然后交给ThreadPool去执 行新的
1 方法体进入了MoveNext,主线程执行 2 开启线程,GetAwaiter(),未完成,重置状态, 交给线程池 3 主线程return 4 线程池线程A获取上下文,递归执行状态机,后 续动作全部由线程A完成 5 多个await就是重复
1 方法体进入了MoveNext,主线程执行 2 开启线程,GetAwaiter(),未完成,重置状态, 交给线程池 3 主线程return 4 线程池线程A获取上下文,递归执行状态机,后 续动作全部由线程A完成 5 多个await就是重
ReadFile对比
Sync:同步,按顺序执行 Task:当然并发---10个线程,速度快 Async: 可以并发,但是并发不多---只有3个线程 这里的动作是读硬盘---都是读到当前程序里面,会很卡---不仅 耗时而且卡 ReadAllBytesAsync这里的线程呢? 对不起,这里没有!!!
InvokeWeb对比 Sync:串行的,耗时长 Task:并发高,速度快------10个线程---铁打的10个线程 Async:耗时短一些,并发不够高----少于10个线程,没有影响并发, 能重用就是没事儿了,利用率高一些 其实对电脑负荷比较小, GetResponseAsync这里的线程呢? 对不起,这里没有!!
适合场景
跟第三方交互的(非托管资源,有async版本): 数据库openAsync-Redis Web请求-Api 文件读取 一用到底,否则要等待?那还是有线程在空转,没意义,甚至容易 阻塞死锁 Await为什么能提升吞吐—只负责发命令—然后就忙别的去了—不需 要等待---事儿完成前就不浪费资源---完成后再来线程处理---这里还 能复用
不适合场景
服务器本地计算(CPU密集型,托管资源): 大数据加减乘除, 数据处理 没有Async封装API Socket IO密集型 适合用 CPU密集型 不适合 反而可能影响性能,因为有线程调度 但是用了没啥事儿
await/async总结
语法糖, 同步方式写异步, 增加系统吞吐量, 一用到底, Web开发推荐