Apollo3zehn / FluentModbus

Lightweight and fast client and server implementation of the Modbus protocol (TCP/RTU).
MIT License
188 stars 69 forks source link

NetworkStream disposed #82

Open manuelelucchi opened 1 year ago

manuelelucchi commented 1 year ago

Hi, we are using FluentModbus to connect 24/24 7/7 on a machine. The problem is, after some days of works the library fails with the NetworkStream disposed. Do you have any idea on when this could happen? I have no further informations as for now since it's difficult to reproduce, we'll try with continuous connections and disconnections to avoid the object being disposed

Apollo3zehn commented 1 year ago

Hi, maybe a stack trace could help finding the cause of the issue. Disposing should only happen if the connection times out, I do not think that there is an OutOfMemoryException or a stack overflow that could also maybe lead to disposed network stream.

Which version of FluentModbus do you use and how are you working with the client? Are you disposing the client maybe accidentially?

manuelelucchi commented 1 year ago

I'm trying to get the stacktrace. Apart from this, the usage is something like this

while (!token.IsCancellationRequested)
{
    while (!client.IsConnected)
    {
        try
        {
            client.Connect();
        }
        catch (Exception e)
        {
            // log
        }

        await Task.Delay(Configuration.Polling, token);
    }

    try
    {
        // do stuff
    }
    catch (Exception e)
    {
        // log
    }

    await Task.Delay(Configuration.Polling, token);

    resetCounter++;
    if (resetCounter== resetMax)
    {
        resetCounter= 0;
        client.Disconnect();
    }           
}

if (client.IsConnected)
{
    client.Disconnect();
}

client.Dispose();

And, since the error is repeated continuously, there should not be accidental disposing I guess

manuelelucchi commented 1 year ago

Hi @Apollo3zehn, we managed to corner the issue a bit more. After some tweaking, it's now a NullReferenceException inside the ModbusTcpClient while awaiting ReadHoldingRegistersAsync(unit, address, count, token)

in FluentModbus.ModbusTcpClient.<TransceiveFrameAsync>d__40.MoveNext()
   in FluentModbus.ModbusClient.<ReadHoldingRegistersAsync>d__30.MoveNext()
   in FluentModbus.ModbusClient.<ReadHoldingRegistersAsync>d__29`1.MoveNext()
   in MyNamespace.MyClass.MyMethod.<ReadStandardMatrixAsync>d__7.MoveNext() in

where the parameters are:

and the session properties are:

This happens really randomly so it's really difficult to reproduce

sharpbetter commented 1 year ago

hi, when I quickly switch between server-side connection states, this problem may occur i think, IsConnected check TcpClient connected when TcpClient connection is ready , but _networkStreamnot ready ,

image

I did this

FluentModbus.ModbusTcpClient client = null;
while (true)
{
    try
    {
        if (client == null || !client.IsConnected)
        {
            Console.WriteLine("reconnect ...");
            client = new FluentModbus.ModbusTcpClient();
            client.Connect("127.0.0.1:502");

            Thread.Sleep(200);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"{ex.Message}");
        continue;
    }

    try
    {
        var source = client.ReadHoldingRegisters<byte>(1, 40100, 10);
        Console.WriteLine(BytesToString(source));
    }
    catch (Exception ex)
    {
        Console.WriteLine($"{ex.Message}");
        client.Disconnect();  //  Add this line
    }

    Thread.Sleep(50);
}