简体   繁体   中英

ReadLine() in Visual Studio - System.IO.IOException

I have an application in Visual studio, reading value from serial port and drawing it on a chart. Everything goes perfecly fine, but when I click a close button on the application (or serial port disconnect button), an error occurs:"IOException() was unhandled", and the program highlights the serial1.Readline() command. How can I handle the exception?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Windows.Forms.DataVisualization.Charting;

namespace usart3
{
    public partial class OknoGlowne : Form
    {
        public OknoGlowne()
        {
            string[] mojePorty = SerialPort.GetPortNames();

            InitializeComponent();

            foreach (string port in mojePorty)
            {
                cmbPorty.Items.Add(port);
            }

            cmbBaud.Items.Add(2400);
            cmbBaud.Items.Add(9600);
            cmbBaud.Items.Add(19200);

            btnRozlacz.Enabled = false;
        }
        private volatile string rxString;

        //private byte[] rxByte;
        private Object thisLock = new Object();
        Boolean i = false;
        private void btnPolacz_Click(object sender, EventArgs e)
        {
            i = true;
            serialPort1.PortName = cmbPorty.Text;      
            serialPort1.BaudRate = Convert.ToInt32(cmbBaud.Text);        

            serialPort1.Parity = Parity.None;  
            serialPort1.StopBits = StopBits.One;
            serialPort1.DataBits = 8;        
            serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
            serialPort1.Open();

            btnPolacz.Enabled = false;          
            btnRozlacz.Enabled = true;

    }

        int rt = 0;
        private void btnRozlacz_Click(object sender, EventArgs e)
        {

                serialPort1.Close();
                btnPolacz.Enabled = true;
                btnRozlacz.Enabled = false;


        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

            rt++;


             rxString = serialPort1.ReadLine();
            this.Invoke(new EventHandler(displayText));

        }


        private void displayText(object o, EventArgs e)
        {
            richTextBox1.AppendText(rxString);
            this.chart1.Series["Temperatura"].Points.AddXY(rt, rxString);
        }


        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 nowy = new Form2();
            nowy.Show();
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {

        }

        private void Start2_Click(object sender, EventArgs e)
        {
            Form2 nowy = new Form2();
            nowy.Show();
        }



        private void button1_Click_1(object sender, EventArgs e)
        {
            Form2 nowy = new Form2();
            nowy.Show();
        }
    }
}

I had similar issue.

The IOExcpection is kind of confusing because accordingly to the documentation ReadLine() is not supposed to throw this type of exception. The problem is that ReadLine is in a state of waiting for an EOL character when we close the port. Closing the port stops the thread holding ReadLine in an unsupported state.

For me the solution was to follow this port closure sequence:

  1. Unsubscribe data_reciver method from the port.
  2. Send a port.WriteLine("get serial number") command. The goal is to trig an EOL character in the input_buffer. This will release ReadLine.
  3. Wait until EOL is recieved.
  4. Close the port.

Surround your call with a try/catch block. In the catch you should code in way that you can handle the error by doing something else.

try {    
    rxString = serialPort1.ReadLine(); 
} catch (IOException e) {  
    // or do something else  
}

EDIT:

try {   
    rt++; 
    rxString = serialPort1.ReadLine(); 
    this.Invoke(new EventHandler(displayText));
} catch (IOException e) {  
    MessageBox.Show("Connection is lost");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM