Demuter Ответов: 1

C# - опрос устройства по протоколу TCP/IP


Я попытался опросить устройство, используя протокол Modbus для TCP/IP, и он работает хорошо, но есть проблемы.
Если я запущу этот код на слабом компьютере, то время отклика увеличится и очень сильно...

Разница в скорости опроса составляет около 6 секунд.
Здесь мне помог 0x01AA, были проблемы с опросом по последовательному порту, но я не могу понять, как производительность компьютера влияет на опрос ...

Что я уже пробовал:

public override void Run()
{
    IsRunning = true;
    OnJobStarted?.Invoke(this);
    OnLogMessage?.Invoke(this, "JOB START");
    try
    {
        while (Job.ThreadState == ThreadState.Running && !isJobTerminated)
        {
            var ts = DateTime.Now;
            if (!Ping())
            {

            }
            var es = DateTime.Now;
            var ms = (es - ts).TotalMilliseconds;
            while (!isJobTerminated && (DateTime.Now - ts).TotalMilliseconds <= this.PingInterval * 1000)
                Thread.Sleep(10);
        }
    }
    catch (Exception ex)
    {
        OnLogMessage?.Invoke(this, " RUN: " + ex.Message);
    }
    OnLogMessage?.Invoke(this, "JOB END");
    OnJobEnded?.Invoke(this);
    IsRunning = false;
}

public override bool Ping()
{
    var result = false;
    try
    {
        PingStat.LastPingDateTime = DateTime.Now;
        PingStat.PingInterval = this.PingInterval;

        result = true;
        PingStat.TotalPingCount++;
        if (!result)
            PingStat.ErrorCount++;

        if (result)
        {
            foreach (var md in Children.Where(m => !m.IsSuspended && m.IsEnabled))
            {
                var pingResult = ReadConfiguration(md).ErrorCode == 0;
                Thread.Sleep(10);

                if (pingResult)
                    ReadState(md);
                if (pingResult && md.IsMaskChanged)
                {
                    var maskResult = WriteSingleRegister(md, 0x05FC, md.Mask);
                    md.IsMaskChanged = !(maskResult.ErrorCode == 0);
                }

                md.PingStat.IsLastPingOk = pingResult;
                md.OnPing?.Invoke(md, pingResult);

            }
        }
    }
    catch (Exception ex)
    {
        OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
        result = false;
    }
    finally
    {
        PingStat.IsLastPingOk = result;
        OnPing?.Invoke(this, result);
    }
    return result;
}

public override RcResult ExecuteModBus(RcModBusDevice device, byte[] request, out byte[] answer)
{
    answer = null;
    var result = new RcResult();
    var dt = DateTime.Now;
    Random rnd = new Random();
    try
    {
        OnLogMessage?.Invoke(this, "ExecuteModBus Lock?");
        lock (communication)
        {

            OnLogMessage?.Invoke(this, "ExecuteModBus Lock!");

            using (var tcpClient = new TcpClient())
            {
                tcpClient.Connect(IP, Port);
                tcpClient.SendTimeout = SendTimeout;
                tcpClient.ReceiveTimeout = Math.Max(100, ReceiveTimeout);
                using (var stream = tcpClient.GetStream())
                {
                    dt = DateTime.Now;
                    OnLogMessage?.Invoke(this, "REQUEST->:" + Utils.BytesToHex(request));
                    stream.Write(request, 0, request.Length);

                    var tmp = new byte[0xA0];
                    int dataLength = 0;

                    try
                    {

                        for (dataLength = 0; dataLength < tmp.Length; dataLength++)
                        {
                            tmp[dataLength] = (byte)(stream.ReadByte());
                            tcpClient.ReceiveTimeout = 100 - Properties.Settings.Default.coefIP;
                            Thread.Sleep(0);
                        }

                    }
                    catch (Exception ex)
                    {
                    }

                    if (dataLength < 2)
                        result.ErrorCode = 1;
                    else
                    {
                        var crc = Utils.GetCRC(tmp, 0, dataLength - 2);
                        if (crc[0] != tmp[dataLength - 2] || crc[1] != tmp[dataLength - 1])
                        {
                            result.ErrorCode = 1;
                            result.ErrorText = "Bad CRC";
                        }
                    }
                    answer = new byte[dataLength];
                    Array.Copy(tmp, 0, answer, 0, dataLength);
                }
                OnLogMessage?.Invoke(this, "ANSWER<-:" + Utils.BytesToHex(answer));
                if (device != null)
                    SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now.AddMilliseconds(rnd.Next(-35, -30)), Utils.BytesToHex(answer));
            }
        }
        OnLogMessage?.Invoke(this, "ExecuteModBus UnLock");
    }
    catch (Exception ex)
    {
        SaveToLog(DbID, device.DbID, dt, Utils.BytesToHex(request), DateTime.Now.AddMilliseconds(rnd.Next(-35, -30)), "ERROR", ex.Message);
        OnLogMessage?.Invoke(this, ex.Message + Environment.NewLine + ex.StackTrace);
        result = new RcResult() { ErrorCode = 1, ErrorText = ex.Message };
    }
    return result;
}

Richard MacCutchan

Я подозреваю, что все эти призывы к потоку.Сон не помогает.

Demuter

Я тоже думал об этом ... Я почистил их, но все равно получил тот же результат

Richard MacCutchan

Боюсь, что без дополнительной информации трудно догадаться, в чем может заключаться проблема.

Demuter

Какую дополнительную информацию лучше предоставить?

1 Ответов

Рейтинг:
0

Gerry Schmitz

Вы продолжаете открывать новое соединение каждый раз, когда делаете запрос; вот где вся ваша "задержка". Вы создаете соединение с устройством и держите его открытым, пока вы "отправляете и получаете." Вы закрываете соединение, когда вы "закончили".