简体   繁体   English

C#:使用 Winforms 关闭 SerialPort 的正确方法

[英]C#: Proper way to close SerialPort with Winforms

I have an app where I read from the serialport, everything goes fine, until I close the app.我有一个从串口读取的应用程序,一切正常,直到我关闭应用程序。 When I click on the [X] the app simply hangs, the UI: unresponsive.当我单击 [X] 时,应用程序只是挂起,用户界面:无响应。

I read from the port in the DataReceived event handler, and I close the port when FormClosed happens:我从 DataReceived 事件处理程序中的端口读取数据,并在 FormClosed 发生时关闭端口:

    private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
    {
        mySerialPort.Close();
    }

It's not a bug. 这不是一个错误。

The only reason it would hang when you close it is because in the event handler of your SerialPort object, you're synchronizing a call with the main thread (typically by calling invoke). 它关闭它时它会挂起的唯一原因是因为在您的SerialPort对象的事件处理程序中,您正在与主线程同步调用(通常通过调用invoke)。 SerialPort's close method waits for its EventLoopRunner thread which fires DataReceived/Error/PinChanged events to terminate, but since your own code in the event is also waiting for main thread to respond, you run into a dead lock situation. SerialPort的close方法等待其EventLoopRunner线程触发DataReceived / Error / PinChanged事件终止,但由于事件中你自己的代码也在等待主线程响应,你会遇到死锁情况。

The reason the bug report was closed 'as designed' is because the 'bug' is in your own code. 错误报告“按设计”关闭的原因是因为“错误”在您自己的代码中。

Serial Port hangs while closing 串口在关闭时挂起

This is a known issue with the SerialPort class and described in this Product Feedback article as well as several threads in these forums. 这是SerialPort类的已知问题,在本产品反馈文章中描述,以及这些论坛中的几个主题。 You may notice the "closed by design" dismissal. 您可能会注意到“关闭设计”解雇。

If your application is calling Invoke to process recevied data try calling BeginInvoke instead. 如果您的应用程序正在调用Invoke来处理接收的数据,请尝试调用BeginInvoke。

Instead of: 代替:

this.Invoke(d, new object[] { s, tb });

use: 使用:

this.BeginInvoke(d, new object[] { s, tb });

Simplest solution if you only want to close the port when the app closes, is to just not bother to Close() the port. 如果您只想在应用程序关闭时关闭端口,最简单的解决方案是不要打扰关闭()端口。 The port will still get closed anyway when the app disposes of the serial port. 当应用处理串口时,端口仍会关闭。 The port will be available to be opened again by your app when it restarts, or by other apps that may wish to use the port. 您的应用程序重新启动时可以再次打开该端口,或者可能希望使用该端口的其他应用程序再次打开该端口。

this work very good :这项工作非常好:

 private void Form_FormClosing(object sender, FormClosingEventArgs e)
    {

        if (_serialPort.IsOpen)
        {
            e.Cancel = true; //cancel the fom closing
            Thread CloseDown = new Thread(new ThreadStart(CloseSerialOnExit)); //close port in new thread to avoid hang
            CloseDown.Start(); //close port in new thread to avoid hang
        }
    }

 private void CloseSerialOnExit()
    {
        try
        {
            _serialPort.Close(); //close the serial port
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message); //catch any serial port closing error messages
        }
        this.Invoke(new EventHandler(NowClose)); //now close back in the main thread
    }

    private void NowClose(object sender, EventArgs e)
    {
        this.Close(); //now close the form
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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