如果正在使用的 USB COM 端口已被移除,SerialPort.Close() 会冻结应用程序
SerialPort.Close() freezes application if the USB COM Port in use has been removed
我面对我的应用程序 冻结,当 关闭 .NET C# SerialPort
在当前 COM 端口连接到之后,有已删除。
执行 SerialPort.Dispose()
也会冻结。
我阅读了这篇博客,其中对可能出现的问题进行了一些解释(请谨慎对待):
https://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport
你能帮我解决这个问题吗?
我找到了解决方法,但不确定这是解决问题的好方法。
我正在使用
dmitrynogin / PnP 处理串行 COM 端口 add/remove 事件的优秀库。
private SerialPort _serialPort;
...
private void Main()
{
...
Open(); // Open COM Port
... // Do Stuff
}
...
// COM Port removed event
private void PortCOMRemoved()
{
...
Close(true);
...
}
...
private void Close(bool currentCOMPortRemoved = false)
{
...
if (currentCOMPortRemoved)
{
_serialPort.DtrEnable = false;
_serialPort.RtsEnable = false;
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
// Do not close the COM Port, otherwise, it will freeze
// This is a Bug in SerialPort class management Framework
// On next connexion, it will create a new SerialPort instance
// Application can close itself
}
else
{
_serialPort.Close();
}
...
}
...
private bool Open()
{
bool success = false;
Close();
try
{
_serialPort = new SerialPort();
_serialPort.ErrorReceived += HandleErrorReceived;
_serialPort.PortName = _portName;
_serialPort.BaudRate = _baudRate;
_serialPort.StopBits = _stopBits;
_serialPort.Parity = _parity;
_serialPort.DataBits = (int)_dataBits;
_serialPort.ReadTimeout = 1000;
// We are not using serialPort.DataReceived event for receiving data since this is not working under Linux/Mono.
// We use the readerTask instead (see below).
_serialPort.Open();
success = true;
}
catch (Exception e)
{
Close();
}
return success;
}
尝试 Close()
正确 SerialPort
应用程序冻结。
那么,如果当前 COM 端口已被删除,为什么不关闭它呢?
稍后当再次插入 COM 端口时,调用 Open()
将创建一个新的 SerialPort
实例,然后忘记之前未正确关闭的 SerialPort
实例。然后应用程序不会冻结,可以正常关闭。
我试过了,它正在作为一种变通方法工作,希望有人能找到更好的解决方案。
另一种方法是通过 SerialPortStream 绕过原生 .Net SerialPort class:
jcurl / SerialPortStream
System.IO.Ports.SerialPort 和 SerialStream 的独立实现,具有更好的可靠性和可维护性。
此致
我面对我的应用程序 冻结,当 关闭 .NET C# SerialPort
在当前 COM 端口连接到之后,有已删除。
执行 SerialPort.Dispose()
也会冻结。
我阅读了这篇博客,其中对可能出现的问题进行了一些解释(请谨慎对待): https://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport
你能帮我解决这个问题吗?
我找到了解决方法,但不确定这是解决问题的好方法。
我正在使用 dmitrynogin / PnP 处理串行 COM 端口 add/remove 事件的优秀库。
private SerialPort _serialPort;
...
private void Main()
{
...
Open(); // Open COM Port
... // Do Stuff
}
...
// COM Port removed event
private void PortCOMRemoved()
{
...
Close(true);
...
}
...
private void Close(bool currentCOMPortRemoved = false)
{
...
if (currentCOMPortRemoved)
{
_serialPort.DtrEnable = false;
_serialPort.RtsEnable = false;
_serialPort.DiscardInBuffer();
_serialPort.DiscardOutBuffer();
// Do not close the COM Port, otherwise, it will freeze
// This is a Bug in SerialPort class management Framework
// On next connexion, it will create a new SerialPort instance
// Application can close itself
}
else
{
_serialPort.Close();
}
...
}
...
private bool Open()
{
bool success = false;
Close();
try
{
_serialPort = new SerialPort();
_serialPort.ErrorReceived += HandleErrorReceived;
_serialPort.PortName = _portName;
_serialPort.BaudRate = _baudRate;
_serialPort.StopBits = _stopBits;
_serialPort.Parity = _parity;
_serialPort.DataBits = (int)_dataBits;
_serialPort.ReadTimeout = 1000;
// We are not using serialPort.DataReceived event for receiving data since this is not working under Linux/Mono.
// We use the readerTask instead (see below).
_serialPort.Open();
success = true;
}
catch (Exception e)
{
Close();
}
return success;
}
尝试 Close()
正确 SerialPort
应用程序冻结。
那么,如果当前 COM 端口已被删除,为什么不关闭它呢?
稍后当再次插入 COM 端口时,调用 Open()
将创建一个新的 SerialPort
实例,然后忘记之前未正确关闭的 SerialPort
实例。然后应用程序不会冻结,可以正常关闭。
我试过了,它正在作为一种变通方法工作,希望有人能找到更好的解决方案。
另一种方法是通过 SerialPortStream 绕过原生 .Net SerialPort class: jcurl / SerialPortStream System.IO.Ports.SerialPort 和 SerialStream 的独立实现,具有更好的可靠性和可维护性。
此致