G
Guest
I am reading binary data returned from a serial device using
SerialPort.Read(). I am finding that only the first byte of the 5 bytes I
requested is being returned due to the way SerialPort.ReadTimeout is
implemented. Using .NET Reflector and sysinternal PortMon I can see that
SetCommTimeouts is being called with ReadIntervalTimeout and
ReadTotalTimeoutMultiplier set to -1 (MAXDWORD). According to the
documentation for the COMMTIMEOUTS structure, this will cause an immediate
return if there are any bytes in the buffer, as I am witnessing. This means
that an incomplete packet is returned. If I set a breakpoint after sending a
packet to the serial device and receiving the response, there is enough delay
for the response to build up in the receive buffer and so the code works as
expected.
The correct SetCommTimeouts settings should be ReadIntervalTimeout and
ReadTotalTimeoutMultiplier set to 0. I previously implemented communications
with my serial device in C++ and these settings work as expected.
My first thought for a workaround was to use pinvoke to call
SetCommTimeouts, but the com port handle is internal to SerialPort.
Can anyone suggest another way around this? I don't want to have to resort
to receiving one byte at a time and using a timer as this rather defeats
being able to read multiple bytes with SerialPort.Read().
SerialPort.Read(). I am finding that only the first byte of the 5 bytes I
requested is being returned due to the way SerialPort.ReadTimeout is
implemented. Using .NET Reflector and sysinternal PortMon I can see that
SetCommTimeouts is being called with ReadIntervalTimeout and
ReadTotalTimeoutMultiplier set to -1 (MAXDWORD). According to the
documentation for the COMMTIMEOUTS structure, this will cause an immediate
return if there are any bytes in the buffer, as I am witnessing. This means
that an incomplete packet is returned. If I set a breakpoint after sending a
packet to the serial device and receiving the response, there is enough delay
for the response to build up in the receive buffer and so the code works as
expected.
The correct SetCommTimeouts settings should be ReadIntervalTimeout and
ReadTotalTimeoutMultiplier set to 0. I previously implemented communications
with my serial device in C++ and these settings work as expected.
My first thought for a workaround was to use pinvoke to call
SetCommTimeouts, but the com port handle is internal to SerialPort.
Can anyone suggest another way around this? I don't want to have to resort
to receiving one byte at a time and using a timer as this rather defeats
being able to read multiple bytes with SerialPort.Read().