Я ничего не могу добавить к ответу Ганса, кроме как сказать, что одна из самых больших ловушек, которые я видел, состоит в том, что люди склонны ожидать, что когда срабатывает событие DataReceived, все байты, которые они хотели бы получить, все нет.
например. если ваш протокол сообщений имеет длину 20 байтов, событие DataReceived срабатывает, и вы пытаетесь прочитать 20 байтов. Они все могут быть там, они не могут. Вполне вероятно, что они не будут, в зависимости от вашей скорости передачи.
Вам необходимо проверить свойство BytesToRead порта, с которого вы читаете, и прочитать это количество в свой буфер. Если и когда будет доступно больше байтов, событие DataReceived будет запущено снова.
Обратите внимание, что событие DataReceived будет запущено, когда число байтов для приема будет, по крайней мере, равно свойству ReceivedBytesThreshold последовательного порта. По умолчанию я считаю, что это значение равно 1.
Если вы установите это значение, например, равное 10, событие сработает, когда ожидается получение 10 или более байтов, но не меньше. Это может вызвать или не вызвать проблемы, и я лично предпочитаю оставить значение этого свойства равным 1, чтобы все полученные данные инициировали событие, даже если получен только 1 байт.
Не допускайте ошибки в том, что это вызовет событие для каждого полученного байта - он этого не сделает.