.NET Framework 4.7.2 WebAPI浏览器刷新后所有请求挂起问题排查求助
.NET Framework 4.7.2 WebAPI浏览器刷新后所有请求挂起问题排查求助
各位大佬好,我遇到一个非常诡异的问题,网上搜了一圈都没找到相关线索,实在没办法了来求助!
先说说我的场景:我在写一个.NET Framework 4.7.2的WebAPI控制器,其中有个接口会执行一个耗时很长的数据库查询。下面是简化后的伪代码:
static bool _isRefreshing = false; [HttpGet, Route("endpoint")] void EndpointContainingLongRunningMethod() { if (_isRefreshing) return ...// 返回"请求处理中"的提示; _isRefreshing = true; // 启动后台任务执行 heavy query var task = new Task<resulttype>(()=>{ using (var scon = new SqlConnection(connectionString)) using (var scom = new SqlCommand()) { scom.Connection = scon; scom.CommandText = "HEAVY QUERY"; using (var reader = scom.ExecuteReader()) { while(reader.Read()) { // 处理数据逻辑 } } } }); task.Start(); _isRefreshing = false; return ...; }
问题复现步骤
- 第一次调用该接口,后台开始执行耗时查询
- 后续调用接口会正常返回"请求处理中"的提示,此时一切正常
- 但如果在后台查询未完成时刷新浏览器,诡异的情况出现:之后不管调用控制器的哪个接口,所有请求都会一直处于pending状态,直到某个超时时间结束或者后台查询完全完成才会被处理。更奇怪的是我打了断点根本触发不到,说明请求压根没进入接口逻辑。
我已经确认过:
- 后台任务是在独立线程运行的,任务内部
HttpContext.Current为空,不存在上下文共享的问题 - 只要把SQL查询替换成
Thread.Sleep(60000),哪怕刷新浏览器也不会出现请求挂起的情况,所以问题肯定和SqlDataReader有关
我试过的无效方案
- 改成非异步方式,单独新增一个接口用于查询处理状态
- 把数据库操作移到非WebAPI类中,排除会话锁的影响
- 修改IIS应用池设置,将"Maximum worker processes"设为0
- 在连接字符串中开启/关闭连接池
- 谷歌、Stack Overflow搜了各种相关关键词,都没找到类似案例
现在我完全搞不懂了:为什么正常情况下一切没问题,只要刷新浏览器就会导致所有后续请求挂起?有没有大佬遇到过类似问题,或者能给点排查方向?
备注:内容来源于stack exchange,提问作者Sotem
相关产品推荐
相关产品推荐

