c# - 关闭 USB 串行端口会使端口不可用
问题描述
我的应用程序使用基于 USB 的串行端口连接到物理硬件设备。我可以打开任何有效的 USB 端口并与外部设备通信。但是,当我关闭连接时,USB 端口会在一段时间内处于某种不确定状态,在此期间进一步尝试重新连接会导致“访问端口“COM--”被拒绝”错误。但是,几秒钟后,尝试重新连接成功。如何确定 USB 端口何时再次支持新连接?
代码如下所示:
private void Setup(string Port)
{
bool ValidPort = false;
int CloseSleep = 10;
_PortName = Port;
_PortType = this;
string[] AvailablePorts = SerialPort.GetPortNames();
foreach(string aPort in AvailablePorts)
{
if (aPort == _PortName)
{
// The required port is listed in the list of available ports)
ValidPort = true;
break;
}
}
if (ValidPort)
{
try
{
if (_ThePort != null)
{
_ThePort.Close();
_ThePort.DataReceived -= ReceivedDataEventHandler;
while(CloseSleep-- > 0)
System.Threading.Thread.Sleep(100);
_ThePort.Dispose();
_ThePort = null;
}
}
catch (Exception ex)
{
EMS_Config_Tool.ModalDialog md = new EMS_Config_Tool.ModalDialog("Closing Port: " + ex.Message, "System Exception");
md.ShowDialog();
}
System.IO.Ports.SerialPort TheNewPort = new System.IO.Ports.SerialPort(Port, 38400);
// Setup the event handlers from Tx and Rx
Handler.DataOutEvent += CommsSender;
TheNewPort.DataReceived += ReceivedDataEventHandler;
TheNewPort.DataBits = 8;
TheNewPort.Parity = Parity.None;
TheNewPort.Handshake = System.IO.Ports.Handshake.None;
TheNewPort.StopBits = System.IO.Ports.StopBits.One;
// We will try 3 times to open the port, and report an error if we fail to open the port
try
{
TheNewPort.Open();
}
catch (Exception)
{
System.Threading.Thread.Sleep(1000);
try
{
TheNewPort.Open();
}
catch (Exception)
{
System.Threading.Thread.Sleep(1000);
try
{
TheNewPort.Open();
}
catch (Exception ex)
{
EMS_Config_Tool.ModalDialog md = new EMS_Config_Tool.ModalDialog("Opening Port: " + ex.Message, "System Exception");
return;
}
}
}
最后的 catch 语句是发出有关 Access 被拒绝的错误的地方。请注意,我尝试重试打开端口 3 次并没有真正帮助。如果我将端口单独放置大约 5 到 10 秒,然后重试调用 Setup 方法,它会立即成功。
解决方案
正如@Neil 所说,有很多问题。在我看来,最好的办法是将搜索置于一个循环中,只要端口可以打开,它就会打开。
我曾经这样做过:
public Task WaitingPort()
{
while (port is null)
{
port = CheckPort();
}
}
private SerialPort CheckPort()
{
string[] listPort = SerialPort.GetPortNames();
foreach(string namePort in listPort)
{
SerialPort port = new SerialPort(namePort, 9600);
if (!port.IsOpen)
{
try
{
port.Open();
port.ReadTimeout = 1500;
string data = port.Readline();
// I programmed my device to send an "A" until it receives
// "777" to be able to recognize it once opened
if (data.Substring(0, 1) == "A")
{
port.ReadTimeout = 200;
port.Write("777"); // to make it stop sending "A"
return port;
}
else
{
port.Close();
}
}
catch (Exception e1)
{
port.Close();
}
}
}
return null;
}
当然,这只是某种模板,您必须对其进行改造以适应您的使用
推荐阅读
- python-3.x - 如何使用 wordcloud STOPWORDS 从 txt 文件中调用停用词
- jestjs - Jest + Enzyme - 测试组件对用户的可见性
- angular - 当用户在线时发出发布请求,否则存储在本地存储中
- spring - 从异步 http 调用传递状态而不阻塞线程
- lstm - 使用 RNN/LSTM 进行预测时的隐藏状态是什么?
- azure-devops - 有没有办法让这个更新构建的管道变量?
- google-cloud-platform - 写入已挂载的文件系统时出现 OSError 输入/输出错误
- heroku - Flask route /predict 在返回对象上返回名称错误
- django - How to properly create JSON arrays from two database table using Django
- sql - 成本较低的 SQL 查询比成本较高的查询运行得慢