有很多方法可以限制异步I/O操作和/或它们的继续执行,比如使用自定义调度程序、SemaphorSlim等。我的问题是:在标准的ASP.NET MVC/WebAPI场景中这样做是否有意义?
我们有一个典型的企业API,作为面向客户的SPA的后端。许多API请求涉及调用许多下游Web服务,我们现在大多数情况下都已经转换为使用TAP(async/await)进行异步I/O。其中许多远程服务调用是并行启动的,没有等待,然后使用Task.WhenAll
批量等待。有时候,WhenAll是在固定数量的任务上完成的,有时候我们会针对集合中的每个项目启动一个远程调用——这会导致产生未知(但通常较少,少于十个)数量的任务,然后使用WhenAll等待它们。
据我理解,这会导致这些任务的连续性(即反序列化其响应的逻辑)在线程池上计划。这引出了我的问题:在并行运行这些CPU密集型连续性时,是否会对线程池施加过多压力?我们是否应该开发某种中间件,通过将它们调度到自定义调度程序来限制单个请求内启动的异步I/O任务的连续性并发性?
这样做是否可以通过减少任何给定请求分配的ThreadPool线程数量来提高应用程序的可扩展性,从而在我们开始耗尽ThreadPool线程(或被ThreadPool增长限制)之前,允许更多的并发请求得到服务?
还是说这样做没有什么用,我们应该信任默认的ThreadScheduler+ThreadPool将所有任务安排到可用的CPU核心上,并跨越任意数量的并发请求?