1

I have a SerialPort object I know is configured correctly because I can send data to the port and the DataReceived event is properly raised. However, when I try the solution presented in How to use SerialPort class more reliably which suggests using calls to BeginRead instead of the DataReceived event, my async callback is never invoked, and the call to BeginRead appears to "hang".

        byte[] buffer = new byte[4096];

        void KickoffRead()
        {
            _serialPort.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
            {
                try
                {
                    var actualLength = _serialPort.BaseStream.EndRead(ar);
                    var received = new byte[actualLength];
                    Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
                    DataReceived?.Invoke(received);
                }
                catch (IOException)
                {
                    // nothing yet
                }

                KickoffRead();
            }, null);
        }

        KickoffRead();  

I've tried calling KickoffRead immediately after opening the port, from the DataReceived event, and from a separate thread - none of that makes any difference. I've also tried changing the buffer size to 1 thinking it was waiting for a full buffer - no luck. Further, when I attempt to stop the debugger it hangs and must be forcefully terminated.

I am doing my testing using virtual serial ports (Free Virtual Serial Ports software) but that works just fine when I used DataReceived instead of BeginRead, so I discounted that as the source of the problem.

Dan
  • 1,215
  • 1
  • 10
  • 22
  • Do not use Begin Read with a serial port. Handshaking (hardware or software) is archaic. The Begin Read would need a connection to work which is only achievable with Hardware Controls. – jdweng Nov 16 '18 at 17:57
  • @jdweng I'm puzzled then as to why this is such a heavily promoted solution. – Dan Nov 16 '18 at 20:41
  • The code is really opening a stream which is connected to a virtual port in the driver. So rather than reading the UART directly you are using a buffered stream. You are not connecting to a remote device (or PC). You could be connecting to a USB port with nothing plugged in.So what is the driver using to indicate when the connection really begins?Is it using Data?Maybe a voltage from the external device? Maybe a Ground Closure? It is up to the manufacturer and driver to determine when the start actually begins.IBM users manual for a PC and Microsoft Windows Definition says it is optional. – jdweng Nov 16 '18 at 21:23

0 Answers0