整套ASP.NET线程卡死分析步骤总结(标准化排查套路)
第一步宏观看整体指标!tp回到顶部二、第二步排查托管锁!syncblk回到顶部三、第三步抽卡死线程栈从syncblk里提取OS-TID~~[0xTID]s;!clrstack打印单个卡死线程托管堆栈回到顶部四、第四步结合代码解释「偶发正常、随机卡死」回到顶部五、第五步区分两种死锁、落地修复查看线程池Worker总数、Running/Idle、排队队列特征Running总线程、Idle0、队列积压几千→ 大批量线程永久卡死不释放。初步结论不是瞬时并发高是线程泄漏卡死。看每条MonitorHeld占用数、有无等待的Waiter线程① 有大量等待线程 多lock互相争抢传统Monitor死锁② 只有占用、无等待线程 线程拿着锁卡在业务代码锁是副产品不是元凶你的场景栈出现ManualResetEventSlim.Wait → Task.InternalWait → Task.Wait()→ 锁定同步.Wait()阻塞异步任务上下文死锁。向上追溯业务类定位出事方法ServiceDiscovery、MatrixHelper、HttpModule、Controller。命中缓存/连接复用GetAsync同步执行完毕返回已完成Taskawait不放线程全链路顺行正常释放真实跨网IO返回未完成Taskawait释放工作线程IO完成回调要切回AspNetSynchronizationContext但主线程被.Wait()占死 → 闭环死锁、线程永久滞留。传统lock死锁A拿锁1等锁2、B拿锁2等锁1 → 改锁顺序、缩小lock范围

相关新闻