Search code examples
c#multithreadingcom0com

application hangs when closing a listening port


I'm using com0com to create a part of virtual ports comA/comB, typing the input to comA from hyperterminal and listening on comB in a wpf application. When I run the following code (by triggering Connect), the application successfully connects and is able to get the data from comA, but hangs when I do Disconnect.

    public void Connect()
    {
        readPort = new SerialPort("COMB");
        readPort.WriteTimeout = 500;
        readPort.Handshake = Handshake.None;
        readPort.Open();

        readThread = new Thread(Read);
        readRunning = true;
        readThread.Start();

        System.Diagnostics.Debug.Print("connected");
    }

    public void Disconnect()
    {
        if (!readRunning)
        {
            readPort.Close();
        }
        else
        {
            readRunning = false;
            readThread.Join();
            readPort.Close();
        }
        System.Diagnostics.Debug.Print("disconnected");
    }

    public void Read()
    {
        while (readRunning)
        {
            try
            {
                int readData = 0;
                readData = readPort.ReadByte();
                System.Diagnostics.Debug.Print("message: " + readData.ToString());
            }
            catch (TimeoutException)
            {
            }
        }
    }

I tried changing the Read function to a write by using

byte[] writeData = { 1, 2, 3 };
readPort.Write(writeData, 0, 3);

instead of port.readbyte, and it starts working perfectly when disconnecting. Does anyone know if there is anything different about readbyte that could have caused the freeze? Or is it possibly related to com0com?


Solution

  • Just checking back, in case anyone runs into the same issue, I found an alternative way overriding SerialPort.DataReceived like this:

        public override void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            byte[] buf = new byte[sp.BytesToRead];
            sp.Read(buf, 0, buf.Length);
            receivedDataDel(buf);
        }