为何在WebService中使用Async异步编程?
你疑惑的点在于把async/await的作用局限在了UI响应上,但在ASP.NET Core Web API场景里,它的核心价值是提升服务器的吞吐量,关键在于线程池资源的高效利用——这也是Steve Smith建议尽量用async的原因。
先理清一个基础事实
ASP.NET Core处理请求的工作线程来自线程池,而线程池的线程数量是有限的(默认和CPU核心数挂钩,可配置但不会无限扩容)。如果所有请求都用同步阻塞的方式处理,线程会被死死占着等待IO操作(比如数据库查询、调用外部API、读写文件),这段时间里它什么都干不了,也没法去处理其他进来的请求。
Await到底在干嘛?
当你await一个IO-bound任务时,当前的工作线程会被立即放回线程池,去处理其他待处理的请求。等IO操作完成后,线程池会再分配一个线程(不一定是原来的那个)来继续执行当前请求剩下的逻辑。
简单说:await不是让线程等,而是让线程“先去忙别的,完事了再回来找我”。
逐个解答你的疑问
为什么同步请求也要用await?
同步请求如果阻塞线程,会导致线程池资源被快速耗尽,后续请求只能排队等待,服务器能同时处理的请求数会暴跌。异步模式下,线程不会空等IO,资源利用率大幅提升,服务器能服务更多用户。线程切换不会增加总处理时间吗?
首先,IO-bound场景下,await带来的线程切换成本极低(ASP.NET Core的异步模型做了大量优化),和线程空等浪费的资源比起来完全可以忽略。其次,单个请求的总处理时间几乎没变化,但服务器能同时处理更多请求,整体吞吐量上去了——这才是Web API最看重的指标。无需并行的场景,await意义何在?
async/await不是为了并行(并行是同时做多件事),而是为了非阻塞。比如一个请求要等数据库200ms,同步时这个线程卡200ms,异步时这200ms里线程能处理另外10个请求,服务器的处理能力直接翻几倍。耗时任务为何要用async?
Web API里的耗时任务大多是IO-bound的(不是CPU密集型计算),线程空等就是纯粹的资源浪费。如果是CPU-bound任务,async确实没太大必要,但这类场景在Web API里占比极低。
举个直观的例子
假设服务器线程池有4个线程,来了10个请求,每个请求都需要等待数据库响应200ms:
- 同步处理:前4个请求占着线程,剩下6个必须等前面的线程释放,总处理时间大概要1000ms(分3批处理)。
- 异步处理:每个请求await时线程放回池,10个请求可以几乎同时启动IO操作,总处理时间只需要200ms多一点,吞吐量直接差5倍。
内容的提问来源于stack exchange,提问作者Eric Ouellet

