原副标题:.Net Core中无所不在的Async/Await是怎样提高操控性的?
产品目录
一、概要 二、Async/Await有甚么用? 1.Async/Await用语实例 2.async/await的特征 3.async/await能提高操控性吗? 4.标识符仔细分析表明返回顶端
一、概要
Async/Await在.Net Core中吗是无所不在,四处都是触发器操作方式,那为什么会用?有甚么促进作用?自己说能提高操控性?网路上一大堆该文看的绕晕了也没说确切,
因此这儿从方法论,课堂教学,基本原理无数个找出那些疑点。
返回顶端
二、Async/Await有甚么用? 1.Async/Await用语实例
用法很单纯,这儿就不详尽说具体内容是不是用了,只提供更多两个实例,他们的最终目标是科学研究它的促进作用。
publicclassAsyncAwaitTest { publicvoidStart( ) { Console.WriteLine($”aaa,缓存Id: {Thread.CurrentThread.ManagedThreadId}” ); AsyncMethod; Console.WriteLine( $”eee,缓存Id: {Thread.CurrentThread.ManagedThreadId}” ); Console.ReadLine; } publicasyncTask< bool> AsyncMethod( ) { Console.WriteLine($”bbb,缓存Id: {Thread.CurrentThread.ManagedThreadId}” ); awaitTask.Run( => { Thread.Sleep( 500); Console.WriteLine($”ccc,缓存Id: {Thread.CurrentThread.ManagedThreadId}” ); }); Console.WriteLine( $”ddd,缓存Id:{Thread.CurrentThread.ManagedThreadId}” ); returntrue; } }2.async/await的特征
1)不会阻塞缓存
从实例的执行顺序,可以看出,当执行async/await方法时,主缓存遇到await关键字,主缓存就返回执行“eee”,然后释放,而不是等待,新开了两个子缓存6执行另外的业务,await前面的方法还是主缓存执行,await后面的方法,等缓存6执行完了再继续执行。
2)同步的方式写触发器
虽然用了触发器,但还是等待执行结果再往下执行,执行流程是同步的。
3.async/await能提高操控性吗?
这个应该是大家最关心的问题了。
能提高单个请求的操控性吗?
答案是不能的。很明显看到,await等待了结果再执行后面的逻辑,还是串行的,执行完该多少秒还是多少秒, 中间还切换缓存去处理了,相比同步来说还多了切换缓存的损耗。
那async/await的意义何在?
在于多请求并发处理,且资源有限的时候,能增加吞吐量(单位时间处理的请求),增加cpu的利用率。
单纯说就是有10个缓存,每个缓存的速度没有提高,然后居然QPS能提高?!
先来看一段微软官网的描述
此模型可很好地处理典型的服务器方案工作负荷。由于没有专用于阻止未完成任务的缓存,因此服务器缓存池可服务更多的Web请求。
考虑使用两个服务器:两个运行触发器标识符,两个不运行触发器标识符。对于本例,每个服务器只有5个缓存可用于服务器请求。此字数太小,不切实际,仅供演示。
假设这两个服务器都接收6个并发请求。每个请求执行两个I/O操作方式。未运行触发器标识符的服务器必须对第6个请求排队,直到5个缓存中的两个完成了I/O密集型工作
并编写了响应。此时收到了第20个请求,由于队列过长,服务器可能会开始变慢。
运行有触发器标识符的服务器也需要对第6个请求排队,但由于使用了async和await,I/O密集型工作开始时,每个缓存都会得到释放,无需等到工作结束。
收到第20个请求时,传入请求队列将变得很小(如果其中还有请求的话),且服务器不会慢。
尽管这是两个人为想象的实例,但现实世界中其工作方式与此类似。事实上,相比服务器将缓存专用于接收到的每个请求,使用async和await能够使服务器处理两个数量级的请求。
注意上面官网描述的 I/O密集型。甚么样的是I/O密集型呢?,就是cpu操控性比硬盘内存好太多,大部分时间都是cpu在等IO的读写操作方式。例如读文件,读文件的时候是不需要cpu参与的,只需要发两个命令给硬盘,硬盘读完文件会再通知cpu继续处理,这种叫 DMA技术。
DMA(Direct Memory Access,直接 存储器 访问) 是所有现代电脑的重要特色,它是指一种高速的数据传输操作方式,允许在外部设备和存储器之间直接读写数据,既不通过cpu,也不需要cpu干预。
这个时候触发器就显出它的优势来了,比如读文件需要1s,如果是同步操作方式,那么就有两个缓存在等1s再往下执行。如果是触发器的,读文件的时候,这个缓存就释放了,等读完文件,硬盘通知cpu再派两个缓存接着处理,那中间的1秒,原来的缓存就可以去处理其他请求了。
4.标识符仔细分析表明
publicclassHomeController: Controller { ///<summary> ///同步请求 ///</summary> ///<param name=”path”></param> ///<returns></returns> publicstringGetData( ) { varresult = System.IO.File.ReadAllBytes( @”F:\package\package.rar”); return“ok”; }///<summary>///触发器请求 ///</summary>///<param name=”path”></param>///<returns></returns>publicasyncTask< string> GetDataAsync2( ) {varresult = awaitSystem.IO.File.ReadAllBytesAsync( @”F:\package\package.rar”); return“ok”; }}
同步请求的流程为
可以看出,硬盘在读取文件时,缓存是在等待的,这时候缓存1在这1s中是不工作的,空等状态。
触发器请求的流程为
触发器请求时,缓存1遇到await关键字,发出命令就返回,然后释放掉了,硬盘读完数据会通知cpu,这时cpu派两个新的缓存去接着处理,
因此,读文件的这1s,缓存1可以去处理其它请求了,没有空等,这就是提高了cpu的利用率,单位时间内处理的请求数就变大了。
cpu密集型的触发器是不能提高QPS的,下面标识符就是cpu密集型的。
cpu密集型:计算密集型,硬盘、内存操控性比cpu好很多,或不太需要访问I/O设备。
///<summary>///触发器请求 ///</summary>///<param name=”path”></param>///<returns></returns>publicasyncTask< string> GetDataAsync2( ) {awaitTask.Run( => { Thread.Sleep( 100); //模拟业务处理耗时});return“ok”; }这儿前面主缓存遇到await虽然释放了,但await里面又有两个缓存接着工作,cpu(缓存)并没有空闲
I/O密集型中IO的操作方式有哪些呢?
文件读写、http请求、数据库请求、redis请求。。。等等。
开发中哪些推荐用触发器呢?
Web开发推荐、有Async的API的,Action、Filter、数据库访问、中间件等等。。。
关注公众号: DotNet开发跳槽
觉得不错,请点个在看 呀