chenrui353 2025-11-29 16:45 采纳率: 0%
浏览 6

运行环境导致线程异常问题排查

最近在做一个上位机项目,要同时控制多个三菱PLC(不同IP地址),每个PLC都是新建一个单独线程来交互
在本机用VS调试运行时,没有问题,所有线程交互都正常,没有任何报错
正常运行日志是这样的

img

现在遇到个很奇怪的问题,在我发布完成,部署到IIS(也是本机的IIS)中后,只有实例化的第一个PLC线程正常,其余的会报错,如下图
配置:


{
  "ParentStation": "OP620",
  "stationChildren": [
    {
      "staioncode": "OP620",
      "stationType": "2", //1 手动模式  2 自动模式
      "PLCAdrress": "192.168.5.153",
      "PLCPort": 5003,
      "Model": "SL_Qna_3E"
    }
  ]
},
{
  "ParentStation": "OP700",
  "stationChildren": [
    {
      "staioncode": "OP700",
      "stationType": "2", //1 手动模式  2 自动模式
      "PLCAdrress": "192.168.5.166",
      "PLCPort": 5002,
      "Model": "SL_Qna_3E"
    }
  ]
}

IIS(本机IIS)中运行报错,如下图

img

然后我将配置文件中的PLC地址调换了一下


{
  "ParentStation": "OP700",
  "stationChildren": [
    {
      "staioncode": "OP700",
      "stationType": "2", //1 手动模式  2 自动模式
      "PLCAdrress": "192.168.5.166",
      "PLCPort": 5002,
      "Model": "SL_Qna_3E"
    }
  ]
},
{
  "ParentStation": "OP620",
  "stationChildren": [
    {
      "staioncode": "OP620",
      "stationType": "2", //1 手动模式  2 自动模式
      "PLCAdrress": "192.168.5.153",
      "PLCPort": 5003,
      "Model": "SL_Qna_3E"
    }
  ]
}

IIS(本机IIS)中运行报错,如下图

img

所以得出结论为,VS的调试环境与本机的IIS运行环境不同,但我在VS中又无法复现,但这个不同点如何排查呢?感谢!

  • 写回答

3条回答 默认 最新

  • 檀越@新空间 2025-11-29 17:05
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你遇到的问题是运行环境差异导致线程异常,在本地调试时没有问题,但在部署到 IIS 后出现部分线程失败。这通常是因为IIS 运行环境与 Visual Studio 调试环境存在差异,尤其是在多线程、网络通信、权限、依赖项等方面。


    一、问题分析

    1. 运行环境差异

    • Visual Studio 是一个开发环境,其默认使用的是 ASP.NET Development Server(即 Cassini) 或者 IIS Express,这些环境对线程、网络等资源的限制较少。
    • IIS(本机) 是一个生产环境,它对资源管理、线程池、超时、权限等有更严格的控制。

    2. 可能原因总结

    • 线程池限制:IIS 中默认的线程池数量有限,可能导致多个线程无法同时运行。
    • 权限问题:IIS 应用程序池的运行账户可能没有足够的权限访问网络资源或文件系统。
    • 网络配置差异:IIS 可能对防火墙、端口、IP 地址有额外的限制。
    • 依赖库版本不一致:某些 DLL 在 IIS 环境中缺失或版本不同。
    • 超时设置不同:IIS 的请求超时时间较短,可能导致长时间操作被中断。
    • 日志输出方式不同:IIS 下的日志输出方式可能与 VS 不同,导致错误信息未被捕获或显示。

    二、排查步骤

    1. 检查应用程序池配置

    • 身份验证方式:确保应用程序池使用的账户具有访问网络设备的权限(如 LocalSystem 或自定义用户)。
    • 托管管道模式:建议设置为 集成模式
    • 启动方式:确保“启用预加载”选项已关闭(避免意外重启)。

    加粗重点
    应用池的账户必须拥有对 PLC 网络地址的访问权限,否则会因权限不足导致连接失败。

    2. 检查网络和防火墙设置

    • 确认 IIS 所在主机的防火墙允许出站连接到 PLC 的 IP 和端口(5002/5003)
    • 检查是否启用了 Windows 防火墙,并确保允许相关端口。

    3. 查看 IIS 日志和事件查看器

    • IIS 日志路径C:\inetpub\logs\LogFiles
    • Windows 事件查看器
      • 打开 事件查看器 > Windows Logs > Application
      • 查找与你的应用程序相关的错误信息(如 Application ErrorProcess Exit Code

    4. 捕获异常信息

    • 在代码中添加详细的 try-catch 块,并在异常发生时记录详细信息(包括堆栈跟踪)。
    • 使用 Serilog、NLog 或 ELK 等日志框架,确保在 IIS 下也能捕获异常。

    加粗重点
    在 IIS 下不要依赖调试器输出,应使用文件日志记录所有异常

    5. 检查依赖项是否完整

    • 确保在 IIS 发布后,所有的 DLL 文件都已正确部署。
    • 检查是否缺少 System.Net.SocketsSystem.Threading 等基础库。

    6. 测试线程池限制

    • 在 IIS 中,默认的线程池大小可能不足以支持多个并发线程。
    • 可以尝试通过以下方式增加线程池大小:
    // 在 Global.asax 或 Startup.cs 中
    ThreadPool.SetMinThreads(100, 100);
    ThreadPool.SetMaxThreads(200, 200);
    

    加粗重点
    线程池限制可能是导致后续线程失败的主要原因

    7. 检查 PLC 连接逻辑

    • 检查每个 PLC 实例是否独立创建,且在连接前进行初始化。
    • 确保每个线程都有独立的连接对象(避免共享同一个连接)。

    三、解决方案

    1. 修改线程池设置(代码示例)

    protected void Application_Start()
    {
        // 设置线程池最大和最小线程数
        ThreadPool.SetMinThreads(100, 100);
        ThreadPool.SetMaxThreads(200, 200);
    
        // 其他初始化逻辑
    }
    

    2. 完善异常捕获和日志记录

    try
    {
        // PLC 连接逻辑
    }
    catch (Exception ex)
    {
        // 记录详细日志
        System.IO.File.AppendAllText("log.txt", $"Error: {ex.Message}\n{ex.StackTrace}\n");
    }
    

    3. 调整应用程序池配置

    • 打开 IIS Manager
    • 选择你的站点 -> “高级设置”
    • 修改 应用程序池DefaultAppPool 或新建一个自定义池
    • 进程模型 中设置:
      • Idle Timeout: 0
      • Rapid-Fail Protection: 关闭
      • Start Mode: AlwaysRunning

    4. 检查网络连接

    • 在 IIS 服务器上使用命令行测试连接:
      telnet 192.168.5.153 5003
      telnet 192.168.5.166 5002
      

      如果无法连接,说明网络或防火墙阻止了连接。


    四、结论

    你目前的问题主要来源于 IIS 运行环境与 VS 调试环境之间的差异,尤其是线程池限制、权限控制和网络配置方面。建议你按照上述步骤逐一排查,并特别注意:

    加粗重点
    IIS 环境下务必使用文件日志记录异常信息,避免依赖调试器输出
    线程池限制可能是导致后续 PLC 连接失败的关键因素


    如果你能提供具体的错误信息或日志内容,我可以进一步帮你定位具体原因。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月29日