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

发布于 2024-08-10 05:40:49 字数 277 浏览 2 评论 0原文

我有一个应用程序,我可以从串行端口读取数据,一切正常,直到我关闭该应用程序。当我单击 [X] 时,应用程序只是挂起,UI:无响应。

我从 DataReceived 事件处理程序中的端口读取数据,并在 FormClosed 发生时关闭端口:

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

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.

I read from the port in the DataReceived event handler, and I close the port when FormClosed happens:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

黎歌 2024-08-17 05:40:49

这不是一个错误。

当您关闭它时它会挂起的唯一原因是因为在 SerialPort 对象的事件处理程序中,您正在将调用与主线程同步(通常通过调用调用)。 SerialPort 的 close 方法等待其触发 DataReceived/Error/PinChanged 事件的 EventLoopRunner 线程终止,但由于事件中您自己的代码也在等待主线程响应,因此您会遇到死锁情况。

错误报告“按设计”关闭的原因是因为“错误”存在于您自己的代码中。

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'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.

The reason the bug report was closed 'as designed' is because the 'bug' is in your own code.

拥抱我好吗 2024-08-17 05:40:49

如果您的应用程序正在调用 Invoke 来处理接收到的数据,请尝试调用 BeginInvoke。

代替:

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

使用:

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

If your application is calling Invoke to process recevied data try calling BeginInvoke instead.

Instead of:

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

use:

this.BeginInvoke(d, new object[] { s, tb });
月依秋水 2024-08-17 05:40:49

关闭时串行端口挂起

这是 SerialPort 类的一个已知问题,并在此 产品反馈文章以及这些论坛中的多个主题。您可能会注意到“设计关闭”被解雇。

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. You may notice the "closed by design" dismissal.

节枝 2024-08-17 05:40:49

如果您只想在应用程序关闭时关闭端口,最简单的解决方案就是不去 Close() 端口。当应用程序处置串行端口时,端口仍然会关闭。您的应用程序重新启动时或希望使用该端口的其他应用程序将可以再次打开该端口。

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.

枕头说它不想醒 2024-08-17 05:40:49

这项工作非常好:

 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
    }

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
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文