ASP.NET Core API请求处于挂起状态的排查求助
排查线索整理
检查中间件执行逻辑
既然请求能进入中间件但到不了控制器,挨个排查管道里的中间件:- 确认是否存在同步阻塞操作(比如调用
.Result/.Wait()),ASP.NET Core里这类操作极易引发线程死锁,导致请求挂起。 - 检查中间件里的异步操作有没有漏写
await,未正确完成的异步操作会让请求一直处于等待状态。 - 对比.NET Framework时代的中间件/HttpModule实现,确认迁移到ASP.NET Core中间件时有没有逻辑遗漏,比如原有的请求拦截、处理逻辑是否适配新管道模型。
- 确认是否存在同步阻塞操作(比如调用
排查请求并发限制
- 浏览器对同一域名的并发请求数有默认限制(比如Chrome是6个),如果挂起的请求是在并发数满了之后发起的,会进入等待队列,看起来像挂起。可以试试减少并发请求数或者合并请求测试。
- 检查ASP.NET Core服务器配置:比如Kestrel的
MaxConcurrentConnections或MaxConcurrentRequests设置,是否因为连接数限制导致请求被阻塞。
核对请求本身的差异
- 对比成功请求和挂起请求的请求头、请求体、URL参数:比如挂起请求是不是带了更大的请求体,或者有特殊Header(比如自定义权限头、非标准Content-Type),在中间件处理时出了异常但没抛出。
- 检查是否存在会话冲突,迁移后的会话机制(比如从旧SessionState转成ASP.NET Core Session)有没有配置不当,导致请求被锁定。
排查同步上下文与线程死锁
-.NET Framework和ASP.NET Core的同步上下文机制不一样,迁移过来的代码如果保留了依赖旧上下文的逻辑,容易引发死锁:- 控制器或中间件里的异步方法有没有正确用
await,或者ConfigureAwait(false)使用不当,导致线程阻塞。 - 检查有没有全局静态资源锁,多个请求抢同一锁资源导致挂起。
- 控制器或中间件里的异步方法有没有正确用
启用详细日志定位卡点
- 在
appsettings.json里开启ASP.NET Core的详细日志:
看日志里请求从进中间件到后续步骤的记录,哪个环节停了输出,就是卡点位置。{ "Logging": { "LogLevel": { "Microsoft.AspNetCore": "Debug", "Microsoft.AspNetCore.Http": "Debug" } } }
- 在
检查服务器配置差异
- 如果部署在IIS上,对比原.NET Framework项目的应用池配置(比如管道模式、队列长度),ASP.NET Core应用池要设为无托管代码,确认有没有配置不兼容。
- 检查Kestrel的请求超时设置(
Kestrel:Limits:RequestTimeout),是不是超时时间过短或者未正确处理。
测试简化场景
- 针对挂起的请求,直接在浏览器地址栏发起(排除JS代码影响),或者写个极简测试控制器复现请求逻辑,看是否依然挂起,逐步排查是不是前端JS的问题(比如请求没正确发送、有取消请求的逻辑)。
内容的提问来源于stack exchange,提问作者Michał Turczyn
相关产品推荐
相关产品推荐

