0

I wrote a simple (or so I thought) C# app to read serial data and chart it in a win forms gauge control. The serial data lines occur at 5 second intervals. Problem is, the app stops updating the chart after some number of updates, and I cannot figure out what's happening. Here's the code:

using System;
using System.IO.Ports;
using System.Windows.Forms;

namespace SimplifiedTempChart
{
    public partial class Form1 : Form
    {
        float frcvdata;
        float test;        
        public delegate void DisplayTempChartDelegate(float temperature);
        public DisplayTempChartDelegate _DisplayTempChart;

        public Form1()
        {
            InitializeComponent();            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            _DisplayTempChart = new DisplayTempChartDelegate(DisplayTempChart);
        }

        private void serialDataReceivedEventHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sData = sender as SerialPort;
            string recvData = sData.ReadExisting();
            float.TryParse(recvData, out frcvdata);
            test = frcvdata * 100;
            gaugeControl1.Invoke((MethodInvoker)delegate { _DisplayTempChart(test); });
        }

        public void DisplayTempChart(float temperature)
        {
            gaugeControl1.SetPointerValue("Scale1", "Pointer1", temperature);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SerialPort aSerialPort = new SerialPort("COM17");
            aSerialPort.BaudRate = 9600;
            aSerialPort.Parity = Parity.None;
            aSerialPort.StopBits = StopBits.One;
            aSerialPort.DataBits = 8;
            aSerialPort.Open();
            aSerialPort.DataReceived += new SerialDataReceivedEventHandler(serialDataReceivedEventHandler);
        }
    }
}

I added a breakpoint to indicate when the serialDataReceivedEventHandler is hit. Here's the debug output for a session:

serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit The thread 0x1a04 has exited with code 0 (0x0). serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit The thread 0x2200 has exited with code 0 (0x0). serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit The thread 0x22fc has exited with code 0 (0x0). serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit serialDataReceivedEventHandler hit The thread 0x1720 has exited with code 0 (0x0). The thread 0x18a8 has exited with code 0 (0x0). The thread 0xed0 has exited with code 0 (0x0). The thread 0xf74 has exited with code 0 (0x0). The thread 0x5b4 has exited with code 0 (0x0). The thread 0x1b7c has exited with code 0 (0x0). The thread 0x1d2c has exited with code 0 (0x0).

The 'thread exiting' events really pile up when the app stops updating the chart - that looks suspicious, however I'm not sure and I do not understand how to begin troubleshooting this.

I can restart the chart updating by simply hitting button1 on the form.

Can anyone help?

2 Answers 2

2

I think that your aSerialPort instance is being garbage-collected early. You are declaring it as a local variable, so it becomes ellegible for garbage-collection as soon as your button_1_Click handler exits.

Try declaring aSerialPort as a Form's class member instead in order to root the reference and prevent it from being garbage-collected.

Sign up to request clarification or add additional context in comments.

Comments

0

Not sure what the communication issue is, but

float.TryParse(recvData, out frcvdata);
test = frcvdata * 100;

is not good. Basically you're saying, "try to parse recvData but no matter what happens, no matter the result, even if it didn't parse, multiply the result by 100."

Try instead:

bool parsed = float.TryParse(recvData, out frcvdata);
if (parsed)
{
    test = frcvdata * 100.0;
    // invoke your delegate with known good data...
}
else
    // do something else with parse failure, 
    // maybe print it so you can see why the parse to float failed?

3 Comments

good point. I went ahead and included that just to be safe, however there haven't been any parse failures and the problem still exists.
How large is the value frcvdata? multiply a very large number by 100 could give a floating point error with an exception.
0.0 < frcvdata < 0.99, so that's OK

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.