Joe Z.
Joe Z.

Reputation: 13

c# serial comms issue (threads?)

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?

Upvotes: 0

Views: 254

Answers (2)

BlueStrat
BlueStrat

Reputation: 2304

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.

Upvotes: 2

TomServo
TomServo

Reputation: 7409

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?

Upvotes: 0

Related Questions