You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IIS托管.NET OpenRia服务多线程计算逐次变慢重启恢复问题咨询

问题根因

你的性能下降问题核心来自三个叠加因素:

  1. 原生DLL的线程资源泄漏:你调用的求解线性系统的原生DLL大概率存在线程本地存储(TLS)、句柄泄漏问题,线程池复用这些被污染的线程时,要么执行效率下降,要么被系统标记为异常状态,线程池会主动降低这类线程的调度优先级。
  2. IIS线程池的节流机制:默认ASP.NET线程池的线程注入速度有限,且你当前代码用Task.WaitAll阻塞了当前请求的IIS工作线程,每次请求都会额外占用一个线程池线程。多次请求后可用线程池线程数持续下降,达不到你预期的60并发度。
  3. 你的代码中ParallelOptions使用完全无效:默认ParallelOptions.MaxDegreeOfParallelism值为-1,你直接用它初始化Task数组长度,实际第一次运行时是线程池动态注入到60个线程,后续线程池资源不足时就无法达到该并发度。
修复方案
  • 优先修复原生DLL资源问题:确认每次调用LoadLibrary加载DLL后,在计算结束时执行对应的FreeLibrary释放资源;排查原生DLL的线程相关资源释放逻辑,避免TLS、内存泄漏。
  • 避免线程池线程被污染:如果原生DLL泄漏问题无法快速修复,不要用线程池线程承载计算任务,改为直接创建独立线程执行,计算结束后线程自动销毁,不会被复用:
// 固定并发数为60,不要依赖默认参数
const int MaxConcurrency = 60;
Thread[] threads = new Thread[MaxConcurrency];
for (int i = 0; i < MaxConcurrency; i++)
{
    threads[i] = new Thread(() => StartAnalysis(events))
    {
        IsBackground = true,
        Priority = ThreadPriority.Normal
    };
    threads[i].Start();
}
foreach (var thread in threads)
{
    thread.Join();
}
  • 调整IIS线程池配置,在web.config中添加以下配置,避免线程注入节流:
<configuration>
  <system.web>
    <!-- 最小工作线程和IO线程数设置为高于你的并发数 -->
    <processModel minWorkerThreads="100" minIoThreads="100" />
    <httpRuntime minFreeThreads="90" minLocalRequestFreeThreads="80" />
  </system.web>
</configuration>
  • 优化异步逻辑:如果要继续用Task实现,将阻塞的Task.WaitAll改为异步等待await Task.WhenAll,释放当前IIS工作线程回线程池,减少不必要的线程占用。
  • 可选优化:将ConcurrentStack改为ConcurrentQueue,避免任务顺序倒置带来的调度损耗,不过该调整对核心性能下降问题无影响。

内容的提问来源于stack exchange,提问作者Alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 09:06:03