I have written Windows service, which perform Modbus WriteMultipleRegisters function call over TCP using NModbus library to 3-party devices every 10 minutes (ticks of System.Threading.Timer).
Occasionally this connection hang up open usually during network problems. As the device accepts only one Modbus connection at time and others are refused, connection during all next ticks fail with SocketException - ConnectionRefused.
But the device automatically closes connections which don't respond after short time. Something must keep connection open at my side even for two days. What's more when my Service is restarted, everything is fine again. So there is definitely some forgotten open connection. But I didn't manage to reproduce this bug in dev, so I don't where/when.. connection hang up. I only know that next connection is refused.
I do the modbus function call with this part of code:
using (TcpClient client = new TcpClient(device.ip, 502))
{
using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
{
master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
}
}
device.ip is string containing IP address of device - it's correct, confirmed from SocketException details.
As I'm using using statement dispose is called on both objects. I have looked trough NModbus source code and everything is disposed correctly.
Any idea how its possible that with this code connection is not closed?
I agree with nemec. If you review the documentation for TcpClient.Dispose if does not specifically mention closing the connection. It frees managed and unmanaged resources by default, but it may not correctly tear down the connection.
Try changing your code to:
using (TcpClient client = new TcpClient(device.ip, 502))
{
try
{
using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
{
master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
}
}
catch(Exception e)
{
// Log exception
}
finally
{
client.Close();
}
}
That way you are doing a clean close before dispose and it should clean up even if the Modbus protocol throws some kind of exception.