0

I have a .NET C# class which uses System.IO.Ports.SerialPort for serial port communication. It includes a thread which continuously read the serial port in a loop.

I have always thought that using Exceptions as part of normal program flow was bad, but searching the web I see many examples using blocking Read and TimeoutException to wait for incoming data, like this:

while (true)
{
    try
    {
        serialPort.Read(buffer, offset, count);
        /* Processing code here */
    }
    catch (TimeoutException)
    { }
}

Wouldn't it be better to check SerialPort.BytesToRead() before issuing the Read, like in this example:

while (true)
{
    if (serialPort.BytesToRead() <= 0)
    {
        /* Wait for event signal or similar. */
    }

    serialPort.Read(buffer, offset, count);
    ProcessData();
}
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Oberon
  • 95
  • 2
  • 10
  • 1
    There is an inherent overhead associated with the exception, populating properties, creating stack trace, etc, so using exceptions in normal program flow is generally a bad idea. – Dutts Feb 18 '13 at 10:23
  • 1
    It's ok to use exceptions and suppress them. The timeout exception because you don't have data is ok. The first approach with a high timeout like 2 seconds, make your thread wait almost without using CPU. The second approach forces you to use an spinlock that uses 100% CPU. Except you use a windows only flag process using the DataReceived event. But it will over complicate and also use much more CPU. Look [User3279361 answer]: (http://stackoverflow.com/questions/10172996/mono-or-net-serialport-frequent-reads-result-in-high-cpu) – Gustavo Garcia Feb 21 '17 at 12:53

2 Answers2

1

The second approach is definitely better. Exceptions should not be used to control normal program flow.

Additionally, the first approach will really clutter your debugging experience, especially if you set your IDE to break on every thrown exception.

Eren Ersönmez
  • 38,383
  • 7
  • 71
  • 92
  • Just to clarify, you meant the _first_ approach will really clutter your debugging experience, right? – Oberon Feb 18 '13 at 11:14
  • I dont agree. Sometimes you will get 'serialPort.BytesToRead()== 0' but not everything is yet received. That's why the timeout is considered as the max time to wait for an answer, after which the complete payload is supposed delivered. – Natxo Apr 12 '17 at 10:18
  • @Naxto the question is about using BytesToRead as a means to know when to _start_ reading so that you don't continuously try reading and get timeout exceptions while waiting for a message to arrive. It's purpose is _not_ to know that the whole message has been received. – Eren Ersönmez Apr 12 '17 at 10:44
-1

Do not read the port, you have a special function:

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
     int n = serialPort1.BytesToRead;
     ...
}
ham-sandwich
  • 3,975
  • 10
  • 34
  • 46