Kestrel中使用Thread.Sleep引发请求阻塞的疑问
问题解析:为什么ASP.NET Core同步阻塞请求会让后续请求等待?
这核心是ASP.NET Core和旧版ASP.NET的线程池模型差异,以及同步阻塞操作对线程池的影响:
ASP.NET Core依赖.NET通用线程池处理请求,这个线程池的线程创建策略偏保守:默认最小工作线程数等于CPU核心数,当所有现有线程被占用时,不会立刻新建线程,而是先等待约500ms才会逐步创建新线程。你用
Thread.Sleep(10000)直接占死了当前线程池线程,且睡眠时间远超过线程池新建线程的等待阈值,所以快速发起的第二个请求要么等第一个线程释放,要么等线程池慢悠悠新建线程——在测试场景下就表现为"等待第一个请求完成"。旧版ASP.NET在IIS上使用的是专用ASP.NET线程池,和.NET通用线程池相互独立。这个线程池默认最小线程数更高,新建线程的策略也更激进,不会有长时间的等待,所以当年测试时会觉得每个请求都能快速分配到新线程,不会出现阻塞等待的情况。
补充:你用的是同步阻塞代码(未使用async/await),这类代码会持续占用线程池线程直到执行完毕;如果换成异步代码(比如
await Task.Delay(10000)),线程会立刻释放回线程池处理其他请求——不过你说只是好奇运行机制,这里就不多讲解决方案了。
内容的提问来源于stack exchange,提问作者beseus
相关产品推荐
相关产品推荐

