当前位置:网站首页>(翻译)异步编程:Async/Await在ASP.NET中的介绍
(翻译)异步编程:Async/Await在ASP.NET中的介绍
2022-07-03 06:29:00 【zxy2847225301】
本文翻译自:Async Programming - Introduction to Async/Await on ASP.NET | Microsoft Docs
下面翻译的内容以第一人称进行,由于翻译作者水平有限,有不对的地方请指正
网上很多的教程围绕async/await展开的内容都是以开发客户端应用程序为主。能在Server端中使用async吗?答案是肯定的。本文介绍ASP.NET异步请求相关概念以及对应网络资源的参考链接。本文我不会涉及 async或await的语法,因为我已经写过相关的博客:Async and Await 以及文章:Async/Await - Best Practices in Asynchronous Programming | Microsoft Docs 。本文以介绍async如何在ASP.NET上工作为主。
对于客户端应用( Windows Store, Windows desktop and Windows Phone apps),使用async是为了保证UI的实时响应。对于服务端应用,使用async的好处是scalability(译注:直白翻译是可扩展性,根据上下文推测,scalability可理解为线程可复用性)。Node.js保证scalability的关键是内置的异步特性;.NET的开放Web接口(OWIN)被设计为异步的;ASP.NET也可以设计为异步的,不单单是UI应用。
同步请求VS异步请求
在讲解ASP.NET的Web异步请求处理方式前,让我们先了解一下ASP.NET的Web同步请求的工作方式。例如,当我们向系统请求 database或者Web Api等外部资源时,ASP.NET从线程池中取出一个线程并分配给它,因为是同步方式,请求外部资源也是同步的,线程会被阻塞直到外部调用资源有返回。图1阐述了线程池中有两个线程,其中一个被阻塞等待外部资源返回。

图1 同步等待外部资源
最后,直到外部资源调用返回,线程继续执行该请求。当请求处理完毕和返回给客户端的准备工作完成了,该线程才会回到线程池中(译注:说白了,请求外部资源时,线程一直在等待返回,白白浪费了线程资源)。
线程数量不多时,能很好地工作,但当请求数量大于ASP.NET server能提供的线程数时,就会有请求需要等待可用的线程来处理请求,图2阐述了server同样只有两个线程的线程池,当它收到了客户端发来的3个请求。

图2 只有两个线程的Server收到3个请求
在这种情况下,前两个请求从线程池中分配到线程,每个线程都请求外部资源并堵塞它们的线程。第3个请求没有可能的线程来处理请求,但它的请求已经达到Server端的系统中了,它的请求时间已经开始计算了,这样很容易得到Http 503请求错误(服务不可用)
请思考这种情况,第三个请求一直等待可用的线程,而另外两个线程事实上啥也不干,它们阻塞并等待外部资源返回。它们不在运行态并不分配CPU时间片,当有其它请求过来时,它们就白白浪费了。这种解决方案是使用异步请求。
异步请求处理和同步请求不同,当一个请求过来时,ASP.NET从线程池中取出一个线程来处理请求,这时请求外部资源是异步的,这时,线程会返回到线程池中,图3阐述了只有两个线程的线程池异步处理等待外部资源的工作方式:

图3 异步等待外部资源
最大的不同是,当请求外部资源时,线程已经返回到线程池中了,已经和请求没有任何的联系了。这时,当外部资源返回时,ASP.NET会从线程池中重新分配一个线程给请求,该线程继续往下执行该请求。当请求完毕后,该线程回到线程池中。注意:同一个线程在同步请求的整个生命周期,相反,异步编程,不同的线程分配到同一个请求(在不同时间点)。
这时,当有3个请求过来时,服务端可以处理它们,因为线程已经回到线程池了尽管请求还有异步外部资源需要等待。只要线程池中有空闲的线程,就可以处理新的请求。异步请求使得小量的线程可以请求相对大量的请求。所以ASP.NET的异步代码的优点是scalability(可拓展)。
为何不增加线程池的数量?
为何不增加线程池的大小这个问题经常有人问。答案分两个方面:与阻塞线程池线程相比,异步代码可以进一步扩展,速度也更快。
异步代码可以进一步扩展是因为比阻塞线程使用更小的内存,每个线程需要操作系统分配1MB的堆栈,加上一个不可分页的内核堆栈。这听起来不是很多,但真正当你启动很多线程的时候,你就会发现问题了。所以,异步请求处理比阻塞线程请求内存压力更少。异步代码使得有更多的内存去处理其他事情(如缓存)。
异步代码的拓展速度比阻塞线程更快,因为线程池的线程注入速度受限。在写本文时,速度是一个线程需要两秒。线程注入受限的优点是它避免了同一个线程重复构建或者销毁。考虑到突然有大量的请求涌进来时,当请求使用完所有可用线程时,同步代码很容易有问题,因为剩下的请求只能等待新的线程注入到线程池中。而异步代码会更好地处理突发的大请求量。
后面的不是很感兴趣了,就不翻译了,有兴趣的老铁可以去看看原文。
边栏推荐
- The difference between CONDA and pip
- pytorch练习小项目
- Code management tools
- Mysql database binlog log enable record
- Request weather interface format, automation
- In depth learning
- . Net program configuration file operation (INI, CFG, config)
- Chapter 8. MapReduce production experience
- [LeetCode]404. 左叶子之和
- ThreadLocal的简单理解
猜你喜欢

Project summary --01 (addition, deletion, modification and query of interfaces; use of multithreading)

Zhiniu stock project -- 04

深入解析kubernetes controller-runtime

Kubesphere - Multi tenant management

10万奖金被瓜分,快来认识这位上榜者里的“乘风破浪的姐姐”
![[5g NR] UE registration process](/img/e3/f881d51fba03010de8c45ea480f3f0.png)
[5g NR] UE registration process

In depth analysis of kubernetes controller runtime

Numerical method for solving optimal control problem (I) -- gradient method

Svn branch management

Selenium ide installation recording and local project maintenance
随机推荐
【系统设计】邻近服务
Fluentd is easy to use. Combined with the rainbow plug-in market, log collection is faster
opencv鼠标键盘事件
When PHP uses env to obtain file parameters, it gets strings
[untitled] 5 self use history
arcgis创建postgre企业级数据库
远端rostopic的本地rviz调用及显示
Reinstalling the system displays "setup is applying system settings" stationary
学习笔记 -- k-d tree 和 ikd-Tree 原理及对比
深入解析kubernetes controller-runtime
ruoyi接口权限校验
[system design] proximity service
UNI-APP中条件注释 实现跨段兼容、导航跳转 和 传参、组件创建使用和生命周期函数
PMP notes
Support vector machine for machine learning
“我为开源打榜狂”第一周榜单公布,160位开发者上榜
error C2017: 非法的转义序列
Time format record
Scripy learning
Kubesphere - Multi tenant management