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

在Quartz.Net的IJob实现类中调用EasyModbus出现连接错误如何解决?

问题原因
  • 未主动调用连接方法:你在IJob的Execute方法中直接调用ReadHoldingRegisters读取数据,但全程没有调用你写的ModbusConnect方法建立Modbus TCP连接,modbus实例一直处于未连接状态,因此报连接错误。主窗体逻辑中你应该是提前手动调用了连接方法,所以可以正常运行。
  • Quartz作业实例的生命周期问题:Quartz默认每次触发作业时都会创建一个新的Gorev类实例,你将ModbusClient作为实例字段,每次作业触发得到的都是全新的未初始化连接的客户端对象,无法复用之前的连接状态。
  • 连接方法逻辑错误:你写的ModbusConnect方法逻辑存在问题:如果当前客户端已经处于连接状态,方法会主动断开连接并返回断开后的状态,不符合连接方法的预期功能。
解决方法

推荐采用「每次作业执行时新建连接、读取完成后主动释放连接」的方案,避免长连接因为网络波动断开、多线程并发冲突等问题,修正后的代码示例如下:

public class Gorev : IJob 
{
    private const string Address = "10.100.135.20";
    private const int Port = 502;
    
    public Task Execute(IJobExecutionContext context)
    {
        // 每次执行作业时新建Modbus客户端
        var modbus = new ModbusClient(Address, Port);
        try
        {
            // 主动建立连接
            modbus.Connect();
            if (modbus.Connected)
            {
                int[] frekans = modbus.ReadHoldingRegisters(0x009E, 1);
                // 此处添加你处理frekans数据的逻辑
            }
        }
        catch (Exception ex)
        {
            // 此处添加异常日志记录逻辑,方便排查问题
            Console.WriteLine($"Modbus读取失败:{ex.Message}");
        }
        finally
        {
            // 主动断开连接释放资源
            if (modbus.Connected)
            {
                modbus.Disconnect();
            }
        }
        return Task.CompletedTask;
    }
}

如果你的作业执行频率很高,需要复用连接减少连接开销,可以将ModbusClient注册为单例模式,确保全局只有一个客户端实例,每次执行作业前先判断连接状态,断开的话再重连即可,同时要注意加锁避免多线程并发操作客户端。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:36:03