. net在usb重新连接后无法重新打开串口



我试图在设备拔掉插头后重新打开串行端口。我设计了这个小代码来测试。但是,当重新连接设备并打开端口时,它会抛出IOException。

Console.WriteLine("Hello, World!");
SerialPort sp = new SerialPort("COM6",115200, Parity.None, 8, StopBits.One);
sp.Open();
Console.WriteLine("OPEN");
await Task.Delay(5000); //Here i disconnect the usb
sp.Close();
Console.WriteLine("CLOSE");
await Task.Delay(5000); //Here i reconnect the usb
sp.Open(); //Here it throws IOException, resource already in use
Console.WriteLine("OPEN");

我在python中做了同样的测试,结果完全相同

import serial as s
import time
ser = s.Serial('COM6',115200,parity=s.PARITY_NONE,
stopbits=s.STOPBITS_ONE,
bytesize=s.EIGHTBITS)
#ser.open()
print('Open')
time.sleep(5) #here I unplug the usb
ser.close()
print('close')
time.sleep(5) #here I plug the usb
ser.open() #here throws exception
print('open')

官方MS串行端口库在关闭中有一个bug,它没有真正关闭串行端口,如https://github.com/jcurl/RJCP.DLL.SerialPortStream#21-issues-with-ms-serial-port所报告的,这是串行端口操作的替代库。

这个库是通过NuGet包安装的,它创建了一个从Stream继承的SerialPortStream对象,所以它可以被用作官方的SerialPort。BaseStream来自MS官方库。

下面是一个使用任务和异步操作的小示例,但它也可以与事件处理程序一起使用。

SerialPortStream sps = new SerialPortStream("COM6", 115200, 8, Parity.None, StopBits.One);
byte[] bytes_buff = new byte[300];
sps.Open();
Task.Run(async () =>
{
while (true)
{
int n_bytes = await sps.ReadAsync(bytes_buff.AsMemory(0, 300)).ConfigureAwait(false);
byte[] not_empty_bytes = bytes_buff[0..n_bytes];
Console.WriteLine("nFrame: " + BitConverter.ToString(not_empty_bytes) + "n");
}
});
await sps.WriteAsync(new byte[] { .... });

这个例子是一个简单的代码片段,但是串行端口应该在退出程序之前关闭,以及使用取消令牌读取async的任务。

最新更新