GC blocking serial interrupts?

Hi,

Is it possible for the GC to block execution of a serial data received event? I’m periodically missing some and I’m thinking it could be the GC.

Cheers

I don’t think it will drop data (unless you’re saturated data volume wise) but absolutely, the GC will stop other activities from continuing; I’d expect a data received event to be executed after GC finishes

1 Like

Of course!

I’m currently assuming that I’m reading each byte as it is received, but if the event is delayed by the garbage collector then there could be more than one byte in the serial buffer by the time the event executes.

At 9600 baud each bytes arrives at ~1ms intervals so it’s very likely that this is the case. Thinking about it like that, I’m surprised that I am not seeing this more frequently.

Now I just need to devise an (probably less than!) elegant way of handling this. :think:

I think it’s “BytesToRead” property. Read as many as it tells you, queue/buffer them, and bail.

might be worthwhile to post your code that handles the reading of the com port?

I’m currently using this;

static void GPS_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] buffer = new byte[GPS.BytesToRead];
            GPS.Read(buffer, 0, buffer.Length);

            if (!gps_message_start)
            {
                if ((char)buffer[0] == '$' || (char)buffer[0] == 'G' || (char)buffer[0] == 'P'
                    || (char)buffer[0] == 'R' || (char)buffer[0] == 'M')
                {
                    gps_message_start = true;
                    gpsBuffer[0] = buffer[0];
                    gps_data_i = 1;
                }
            }
            else if (gps_message_start)
            {
                if ((char)buffer[0] == '*')
                {
                    gps_data_i = 0;
                        
                    //Do something with the NMEA string
                    
                    gps_message_start = false;
                }
                else
                {
                    if (gps_message_start)
                    {
                        gpsBuffer[gps_data_i] = buffer[0];
                        gps_data_i++;
                    }
                }
            }
        }

It could definitely miss the ‘’ at the end of the sentence if this event got delayed and the '’ was not the first byte in ‘buffer’. I guess that I always need to loop through ‘buffer’ rather than assume that it is just one byte.

The chances of it missing the start of the sentence are slimmer but I think it’s still possible.

Yes! With serial ports, you should never make assumptions about how many bytes you will read, except if the messages consist of one byte and are separated in time. Use Debug.Print to write out the number of bytes in BytesToRead, and you will see that the number varies…

If GC occurs, then there might be a large number of bytes in the next DataReceived evnt.

1 Like

absolutely agree with Mike. You can’t assume anything. Perhaps the hardware on the sending side buffered a few chars itself and pushed them to you. Perhaps you had some sloppy code elsewhere in your system and you were “late” getting that next character which meant there was two in the buffer (strangely, this is the one that hits me all the time - sloppy code :slight_smile: ) My view is that the datarecieved handler is just a mechanism to know when you need to dequeue content into your own queue, and perhaps you’ll use it to trigger subsequent processing.

1 Like

That’s looking reliable now, I don’t seem to be missing any data.

1 Like