tincho87
tincho87

Reputation: 379

C# virtual serial port timeoutexception on write

i'm having a problem with virtual serial ports in C#: when i call the Write function, it automatically throws a TimeOutException, but the client receives the data.

It only happens with virtual ports (i'm using Free Virtual Serial Ports from HDDSoftware, with a bridge COM12<->COM13). I open COM12 with the Visual Studio and the COM13 with Hercules. The application throws the timeout exception but Hercules receives the message.

It doesn't matter if i set 1000ms or 1000000ms of Read/Write port timeout.

Thanks!!

        using (SerialPort port = new SerialPort("COM13"))
        {
            // configure serial port
            port.BaudRate = 9600;
            port.DataBits = 8;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;
            port.Open();

            port.ReadTimeout = 10000;

            byte[] buffer = Encoding.ASCII.GetBytes("HELLO WORLD");

            try
            {
                port.Write(buffer, 0, buffer.Length);
            }
            catch(TimeoutException)
            {
                Console.WriteLine("Write timeout");
            }

            Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
            try
            {
                byte[] buf = new byte[100];
                port.Read(buf, 0, 1);
            }
            catch(IOException)
            {
                Console.WriteLine("Read timeout");
            }
            Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
        }

After a few tests (putting the Write into a try-catch), the Read operation also throws a TimeOutException instantly.

This is what i get when run the test. It is supposed to be: 12:16:06 (Read timeout) 12:16:16

enter image description here

Upvotes: 3

Views: 4744

Answers (2)

tincho87
tincho87

Reputation: 379

As Hans Passant said, it was a problem with the Virtual COM software. I tried with Virtual Serial Port from Eltima Software and worked fine!

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942247

   port.Write(buffer, offset, count);

It is up to the device driver to decide how to implement this. But all the ones I know follow the rule that the underlying WriteFile() call is allowed to return *lpNumberOfBytesWritten < nNumberOfBytesToWrite. Or to put it another way, the write is not "transactional".

A decent mental model is that Write() writes one byte from the buffer at a time, count times. At some point, entirely unpredictable when, writing one more byte will stall when the driver's transmit buffer fills up to capacity and cannot store another byte. Eventually triggering the exception.

So part of the buffer will still make it to the other end. You cannot tell what part from the SerialPort class. A time-out is a gross communication failure that's pretty hard to recover from. If that's a show-stopper then you need to consider writing one byte at a time (fine, serial ports are slow) or pay attention to WriteBufferSize - BytesToWrite to check if the buffer fits and implement your own timeout.

Upvotes: 2

Related Questions