что вызывает событие DataReceived класса .NET SerialPort? - PullRequest
4 голосов
/ 19 февраля 2010

Из документов MSDN я понимаю, что событие DataReceived не обязательно будет запускаться один раз за байт.

Но кто-нибудь знает, что именно является механизмом, который вызывает событие?

Перезапускает ли прием каждого байта таймер, который должен достигать, скажем, 10 мс между байтами, до того, как событие сработает?

Я спрашиваю, потому что я пытаюсь написать приложение, которое читает данные XML, поступающие из последовательного порта.

Поскольку у моего ноутбука нет последовательных портов, я использую виртуальный эмулятор последовательного порта. (Я знаю, я знаю - я ничего не могу поделать с этим банкоматом).

Когда я передаю данные через эмулируемый порт в мое приложение, событие запускается один раз для каждой записи XML (около 1500 байт). Отлично. Но когда коллега в другом офисе пробует его на двух компьютерах, соединенных реальным кабелем, событие DataReceived запускается многократно, после каждых примерно 10 байтов XML, что полностью сбрасывает приложение.

Ответы [ 2 ]

6 голосов
/ 19 февраля 2010

DataReceived может запустить в любой момент, когда один или несколько байтов готовы к чтению.Точно, когда он запускается, зависит от операционной системы и драйверов, а также будет небольшая задержка между получением данных и событием, запускаемым в .NET.

Вы не должны полагаться на время DataReceivedсобытия для управления потоком.

Вместо этого проанализируйте базовый протокол и, если вы не получили полное сообщение, подождите больше.Если вы получаете более одного сообщения, не допускайте синтаксического анализа первого сообщения оставшимися кадрами, поскольку они будут началом следующего сообщения.

2 голосов
/ 19 февраля 2010

Как отметил Марк Байерс, это зависит от ОС и драйверов. На самом низком уровне стандартная микросхема RS232 (на мой взгляд, я не могу вспомнить обозначение той, которую все скопировали, чтобы сделать «стандартную»), будет запускать прерывание, когда в входящем регистре данных есть данные. «Нижний конец» драйвера должен получить эти данные (которые могут быть в любом размере вплоть до размера буфера чипа), сохранить их в буфере драйвера и сообщить ОС, что у него есть данные. Именно в этот момент .NET Framework может начать обнаруживать, что данные доступны. В зависимости от того, когда ОС подает сигнал приложению, открывшему последовательный порт (что является операцией на уровне ОС, и обеспечивает «реальную» связь от .NET Framework к реализации на уровне ОС / драйвера), может быть буквально любой объем данных > 1 байт в буфере, потому что нижний конец драйвера мог бы загрузить больше данных за это время. Держу пари, что в вашей системе драйвер предоставляет огромный буфер и сигнализирует только после значительной паузы в потоке данных. Система вашего коллеги, с другой стороны, сигнализирует гораздо чаще. Опять же, совет Марка Байера о разборе протокола точен. Я реализовал аналогичную систему через сокеты TCP, и единственный способ справиться с ситуацией - это буферизовать данные до тех пор, пока вы не получите полное сообщение протокола, а затем передать полное сообщение приложению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...