【问题标题】:SerialPort sometimes hangs on closeSerialPort 有时会在关闭时挂起
【发布时间】:2012-09-14 13:28:07
【问题描述】:

我正在用 C# 开发一个 .NET 4.0 WPF 应用程序,它通过 RS232 控制电机。我在退出我的应用程序时遇到问题,在关闭 comport 时应用程序有时会死锁。

在互联网上进行一些研究后,我注意到这是一个常见问题,在 DataReceivedEvent 中使用 BeginInvoke 或在不同的线程中关闭串行端口应该可以解决问题。 这些变通办法的问题在于。 1. 我不使用 DataReceiveEvent。 2.在另一个线程中关闭串口没有任何区别。发生的情况是 GUI 关闭,但您可以在 TaskManager 中看到该进程仍在运行。

我尝试过的其他事情是:

  • 不关闭串行端口而只是退出应用程序。这成功关闭了应用程序和进程,但串口仍然被阻塞,要解除对串口的阻塞,我需要重新启动计算机。
  • 在我关闭串口前后睡了几秒钟。
  • 让应用程序成为 WinForms 应用程序。而不是 WPF。两者的僵局没有区别。

我运行该程序的计算机使用安装在主板上并具有 Microsoft 驱动程序的 com 端口。

现在是一些代码:

Window_Closing 事件如下所示:

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    window.Closing -= Window_Closing;            
    Thread CloseDown = new Thread(new ThreadStart(server.Dispose)); //Closes serialport everything in another thread to avoid hang on serialport close.
    CloseDown.Start();
}

其中server 是管理串行端口的对象。而Dispose调用串口关闭函数。

串口关闭功能:

public void Close()
{
    DebugLog.Write(3, "-->MacCommSerialPort.Close");
    _com.Close();                        
    DebugLog.Write(3, "<--MacCommSerialPort.Close");
}

串口设置:

_com = new SerialPort(portNumber);
_com.BaudRate = 19200;
_com.Parity = Parity.None;
_com.DataBits = 8;
_com.Encoding = Encoding.GetEncoding("Windows-1252");
_com.StopBits = StopBits.One;
_com.RtsEnable = false;
_com.DtrEnable = false;
_com.WriteTimeout = 400;
_com.ReadTimeout = 1000;

【问题讨论】:

  • 您能发布一下您当前如何在底层流中读取和写入数据吗?
  • 而不是尝试关闭串行端口,而是尝试关闭/处理底层流。
  • 写入如下:_com.Write(buffer, offset, count);其中缓冲区是一个字节[]。读取完成为:_com.ReadByte() 我将尝试处理/关闭底层基流,看看是否会产生更好的结果。
  • 终于可以尝试关闭流并测试几天了。不幸的是 BaseStream.Close() 也出现了死锁。还有其他人有其他想法吗?

标签: c# .net serial-port


【解决方案1】:

我只是碰巧看了你的代码,猜想你应该在关闭你的 GUI 之前使用 AutoThreadRest 事件。

private static AutoResetEvent PortClosedEvent = new AutoResetEvent(false);

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 
    { 
        window.Closing -= Window_Closing;             
        Thread CloseDown = new Thread(new ThreadStart(server.Dispose));
        CloseDown.Start(); 
        PortClosedEvent.WaitOne(); 
    } 

在你完成连接处理后,在 server.Dispose 方法中添加下面的代码行。

PortClosedEvent.Set();

【讨论】:

    【解决方案2】:

    我会检查以确保您的应用程序和电机(即发送器和接收器)之间的握手协议匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-22
      • 2017-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多