C# Функция запрос-ответ в System.IO.Ports.SerialPort

231
06 марта 2018, 01:10

Здравствуйте, есть функция которая отправляет в послед порт N байт, и ожидает получение ответа (N байт ответа) заданное время, если данные получены быстрее то остаток времени не ждем а переходим к след. запросу, если за заданное время данные не получены, то считаем что ответа нет.

    /// <summary>
    /// Функция посылает запрос в порт, и как только в буфер порта приходят данные сразу же проверяет их кол-во.
    /// Как только накопится нужное кол-во байт сразу же будет возвращен ответ не дожедаясь времени readTimeout.
    /// Таким образом период опроса не фиксированный, а определяется скоростью ответа slave устройства.
    /// </summary>
    public async Task<byte[]> RequestAndRespawnInstantlyAsync(byte[] writeBuffer, int nBytesRead, int readTimeout, CancellationToken ct)
    {
        if (!_port.IsOpen)
            return null;
        var tcs = new TaskCompletionSource<byte[]>();
        SerialDataReceivedEventHandler handler = null;
        try
        {
            //очистили буферы порта
            _port.DiscardInBuffer();
            _port.DiscardOutBuffer();
            //_port.WriteTimeout = 500; //??????
            _port.Write(writeBuffer, 0, writeBuffer.Length);     //отправили данные в порт
            //ждем ответа....
            handler = (o, e) =>
            {
                if (_port.BytesToRead >= nBytesRead)
                {
                    var buffer = new byte[nBytesRead];
                    _port.Read(buffer, 0, nBytesRead);
                    tcs.TrySetResult(buffer);
                }
            };
            _port.DataReceived += handler;
            var buff = await AsyncHelp.WithTimeout(tcs.Task, readTimeout, ct);
            return buff;
        }
        catch (TimeoutException)
        {
            tcs.TrySetCanceled();
            throw;
        }
        catch (Exception ex)
        {
            StatusString = $"Ошибка работы с портом (DataExchangeAsync): {_port.PortName}. ОШИБКА: {ex}  InnerException: {ex.InnerException?.Message ?? string.Empty}";
            ReOpen();
            return null;
        }
        finally
        {
            _port.DataReceived -= handler;
        }
    }

Я написал класс MasterSerialPort в котром есть очередь выполняющихся по циклу функций запрос-ответов. код работает в боевом режиме уже достаточно давно, но проанализировав логи я примерно раза 3 в сутки замечаю InvalidOperationException на методе _port.Write(writeBuffer, 0, writeBuffer.Length); Этот Exception возникает, если на закрытом порту выполняются действия, но как закрывается порт во время работы я не могу понять. Аппаратная это ошибка или функция обмена написана криво у меня?

READ ALSO
Функция 0x06 Modbus RTU C#

Функция 0x06 Modbus RTU C#

Нашел неплохой пример для работы с протоколом Modbus RTU Code Project

207
Десериализации XML в DataSet

Десериализации XML в DataSet

Сделал dataset сериализацию XMLНо не могу теперь сделать Десериализации в dataset и вывести в грид

216
Ошибка с сохранение в базе данных

Ошибка с сохранение в базе данных

Привет!Я создавал приложение и мне понадобилось добавить в бд данныеВот мой код

233
Редактирование PDF файла

Редактирование PDF файла

У меня есть pdf файл с даннымиМне нужно в него добавить в верхней части каждого листа ссылку на файл

231