2015-07-06 2 views
2

У меня есть поток для чтения и анализа последовательных данных. Сообщения находятся в двоичном формате и начинаются с символов «F», «S», «Q» или «M». Нет новых строк, и нет специального символа окончания (символы выше указывают, что сообщение завершено и все до того, как оно будет готово к анализу).Быстрый подход к постоянному считыванию и анализу последовательных данных

Как я могу читать и анализировать данные?

Все, что приходит на ум, имеющий 4096 байт длиной входного буфера (байт массива), а затем выполните следующие действия:

  • отслеживать положение в буфере вручную
  • Append имеющиеся данные к нему через SerialPort.Read(buffer, position, byteCount)
  • пытаются разобрать столько сообщений, сколько возможно из буфера
  • скопировать остальное во временный буфер
  • сброс входного буфера
  • скопировать содержимое временного буфера исходного буфера
  • установить позицию в буфере

Вы можете думать быстрее/легче подходов?

ответ

2

После приобретения некоторого опыта работы с SerialPort C компонента

# В начале: Возьмите последовательный порт exclusevily.

Тогда:

первая параллель Задача: Продолжает прочитать все содержимое буфера после интервала регулярные и толкает считанную кусок в «Сбор коллекции» данных.

вторая параллельная Задача: Анализирует «Сбор коллекции» для завершенного «фразы», делегирует clonned «фраза» к «Фразе Manager» и исключает эту фразу из «Сбора Коллекция»

у вас есть свобода о „Сбор коллекции“ реализации, но то, что было важно для меня является то, что:

  • прочитал все, но не размер содержимого из последовательного буфера порта

  • , чтобы избежать потерь и сохранить порядок в сообщениях создать свой собственный диспетчер порта, а позволять кому-либо открывать и закрывать порт в любое время чтение/запись.

  • Обнаружение частоты считывания порта экспериментально.Более частая операция чтения позволит вашему коду обнаружить fatser «Фраза» и начать ручную обработку продера. Слишком частое чтение без обнаружения фраза «» может стоить вам дополнительного использования ресурсов.

4

Очень простой способ добиться успеха - прекратить попытки сделать это быстрее. Нет смысла, скорость передачи данных по последовательному порту очень-очень низкая, а современные компьютеры очень и очень быстрые. Ваш Read() вызов только когда-либо возвращает один байт, редко 2.

Обратите внимание, что это трудно понять, когда вы отлаживаете и выполняете однократное выполнение кода, вы значительно искусственно замедляете свою программу. Позволяет получать больше байтов и, следовательно, больше их возвращаются вызовом Read(). Но этого не происходит, когда программа работает с нормальной скоростью.

Таким образом, вместо этого используйте SerialPort.BaseStream.ReadByte(). Делает код очень простой.

+0

Не рискну ли я потерять байты с помощью 'ReadyByte()'? Как определить, что читать нечего? Почему я предпочитаю «BaseStream.ReadyByte()' over 'Read()'? – Hedge

+0

Это ReadByte(), не готов. Нет риска. Вы используете BaseStream, потому что SerialPort не имеет метода для чтения одного байта, вы можете использовать Read() с * count * of 1, если хотите. BytesToRead сообщает вам, сколько из них доступно. –

+0

и почему вы предпочитаете его читать 'Read (buffer, 0, SerialPort.BytesToRead)'? – Hedge

Смежные вопросы