winforms 由于线程退出或串行端口中的应用程序请求,I/O操作已中止

sqxo8psd  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(341)

我正在使用一个窗口应用程序来连续显示来自串行端口的数据。下面是我的代码。当我运行该程序时,我会收到此错误:
“由于线程退出或应用程序请求,I/O操作已中止。”
如何解决此问题?

private void mainform_Load(object sender, EventArgs e)
    {
        this.WindowState = FormWindowState.Maximized;   
        getWGT();           
    }
    SerialPort port = new SerialPort();
    public void getWGT()
    {            
        try
        {

            port.PortName = "COM1";
            port.BaudRate = 9600;
            port.StopBits = System.IO.Ports.StopBits.One;
            port.DataBits = 8;
            port.Parity = System.IO.Ports.Parity.None;

            port.Open();

            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }
   public delegate void myDelegate();
    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {          
        tWGT.BeginInvoke(new myDelegate(updateTextBox));
    }

    public void updateTextBox()
    {
        try
        {
            tWGT.AppendText(port.ReadExisting());
            tWGT.ScrollToCaret();
        }
        catch {
            port.Close();
        }
    }
qgelzfjb

qgelzfjb1#

SerialPort正在线程上使用它自己的Eventloop。当您订阅DataReceived事件时,最好不要在UI线程上阅读端口的数据。您最好将其保留在后台线程上,并在获得所有数据后切换上下文。
我要做的另一个补充是在窗体关闭时调用port.Close。在可以释放SerialPort示例之后。
以下方法已被更改,以包括我上面描述的更改:

// the delegate now takes a string argument, holding the received data
public delegate void UpdateText(string text);

// checks for the correct EventType and calls updateText 
// after all available data is read
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        if (e.EventType == SerialData.Chars)
        {
            // read all data and then handle
            updateTextBox(port.ReadExisting());
        }
        else
        {
            port.Close();
        }
    }
    catch
    {
        port.Close();
    }     
}

// called twice, once from the background thread
// and by BeginInvoke
public void updateTextBox(string text)
{
    // do we need to be switch to the UI thread?
    if (tWGT.InvokeRequired)
    {
        // yes, so setup the delegate and pass on the parameter
        // notice how BeginInvoke will call this same method again
        tWGT.BeginInvoke(new UpdateText(updateTextBox), text);
    }
    else
    {
        // show the received data
        tWGT.AppendText(text);
        tWGT.ScrollToCaret();
    } 
}

// nicely close
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
    // if omitted you'll run into problems if this forms gets reopened
    if (port.IsOpen) port.Close();
    port.Dispose();
}

相关问题