C# – Program crashes after trying to close() serial port

cserial-port

I am writing application to control robot. I have a button click method, which should open or close port.

private void cONNECTToolStripMenuItem_CheckStateChanged(
                 object sender, EventArgs e)
{
    if (cONNECTToolStripMenuItem.Checked)
    {
        cONNECTToolStripMenuItem.Text = "DISCONNECT!";
        ports.connect();
    }
    else
    {
        cONNECTToolStripMenuItem.Text = "CONNECT!";
        ports.disconnect();
    }
}

Furthermore, I have DataReceived event handler, which is called after some data from serial port is received.

private void serialPort_DataReceived(
                 object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string data = sp.ReadExisting();

    mainForm.addData(data);
} 

When this event handler was trying to call addData(data) function

public void addData(string data)
{
    //if (!this.Disposing || !this.IsDisposed || 
    //    !this.listBox1.Disposing || !this.listBox1.IsDisposed)
    if (this.listBox1.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(addData);
        this.Invoke(d, new object[] { data });
    }
    else
        listBox1.Items.Add(data);         
}

there was a cross-thread error, so I wrapped function content into InvokeRequired condition.

Now there is other errors:
1. Program crashes after trying to call ports.disconnect() function

public void disconnect()
{
    serialPort.Close();
}

ports class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace server_client
{
    public class COM_Port
    {
        private Main_Form mainForm;
        public SerialPort serialPort;

        //MySQL - 1, XML File - 2, None - 0
        public int writeStatus;

        public COM_Port(Main_Form form)
        {
            mainForm = form;

            //by default niekur neirasineja nebent pasirenka
            writeStatus = 0;

            //sukuriam serialPort kintamaji
            serialPort = new SerialPort();

            //nustatom duomenis portui
            serialPort.BaudRate = 9600;
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;
            serialPort.ReadTimeout = 500;
            serialPort.WriteTimeout = 500;


        }

        ~COM_Port()
        {
            disconnect();
            serialPort.Dispose();
        }

        public void connect()
        {
            if (!serialPort.IsOpen)
                if (serialPort.PortName != "") 
                    serialPort.Open();
                else
                    MessageBox.Show("Please choose COM Port in settings.");
        }

        public void disconnect()
        {
            //serialPort.DiscardInBuffer();
            //serialPort.DiscardOutBuffer();
            serialPort.Close();
        }

        public void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            string data = null;

            SerialPort sp = (SerialPort)sender;

            if (sp.IsOpen)
                data = sp.ReadExisting();
            else
                data = null;

            //perduoda duomenis atvaizdavimui i maina
            if (data != null)
            {
                mainForm.addData(data);

                switch (writeStatus)
                {
                    //neirasyti
                    case 0:
                        break;
                    //irasyti i mysql
                    case 1:
                        MySQL mysql = new MySQL();
                        break;
                    //irasyti i xml file
                    case 2:
                        File file = new File();
                        break;
                    default:
                        break;
                }
            }
        } 
    }
}

I believe, that after closing the port robot is still sending me data and DataReceived event handler tries to get that data from buffer of serial port.

Thank you for reading this love letter, for your help :).

Best Answer

I've just had this issue myself, the solution is to use BeginInvoke() rather than Invoke() in the SerialPort.DataRecieved eventhandler.

Reference: duplicate question

Related Topic