4

我正在用 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;
4

2 回答 2

3

我只是碰巧查看了您的代码,并猜测您应该在关闭 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();
于 2012-09-26T05:56:27.787 回答
0

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

于 2015-01-29T20:59:06.050 回答