为什么访问com端口被拒绝?

代码:

static void Main(string[] args) { Console.WriteLine("Memory mapped file reader started"); using (var file = MemoryMappedFile.OpenExisting("AIDA64_SensorValues")) { using (var readerz = file.CreateViewAccessor(0, 0)) { var bytes = new byte[567]; var encoding = Encoding.ASCII; readerz.ReadArray(0, bytes, 0, bytes.Length); File.WriteAllText("C:\\myFile.txt", encoding.GetString(bytes)); var readerSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment }; using (var reader = XmlReader.Create("C:\\myFile.txt", readerSettings)) { while (reader.Read()) { using (var fragmentReader = reader.ReadSubtree()) { if (fragmentReader.Read()) { reader.ReadToFollowing("value"); SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); port.Open(); port.Write(reader.ReadElementContentAsString() + ","); } } } } } } Console.WriteLine("Press any key to exit ..."); Console.ReadLine(); } 

它读取共享内存,将共享内存写入文件,然后使用xml reader打开同一文件并拆分xml,因为它有多个根,然后获取每个新拆分xml上的节点值并通过串行发送。 它适用于第一个拆分xml,它的节点通过串口发送然后停止,在尝试将第二个节点写入串口时拒绝访问com端口消息。

我有另一个应用程序,我使用相同的序列代码,它工作正常(我只是累了,然后关闭它。)…所以它很奇怪。

您只能打开一次串口。 但是你的代码在while循环中有Open()调用。 这只适用于第一次通过循环,kaboom在第二次传球。 @ cdhowie的解决方案也不起作用,SerialPort有一个文档警告的怪癖(也就是bug)。 在Dispose()或Close()调用之后,需要时间让工作线程退出。 时间量未指定且不可预测。

真正的解决方案很简单,只需在while循环之前移动Open()调用即可。

除了汉斯的回答:

我有同样的问题,在打开和关闭串口之间有一些睡眠时间。 就我而言,250毫秒就足够了。 也许这会帮助那里的人。

编辑:

我优化了我的解决方案,这就是我想出的:

 int maxRetries = 20; const int sleepTimeInMs = 50; string loggingMessage = string.Empty; while (maxRetries > 0) { try { loggingMessage = "Opening serial port '" + mSerialPort.PortName + "'..."; mSerialPort.Open(); loggingMessage += "Succeeded."; IOLogger.LogInfo(loggingMessage); } catch (UnauthorizedAccessException unauthorizedAccessException) { maxRetries--; loggingMessage += "Failed (UnauthorizedAccessException): "; IOLogger.LogError(string.Format(loggingMessage + unauthorizedAccessException.Message + " -> Retrying in about {0} milliseconds...", sleepTimeInMs)); Thread.Sleep(sleepTimeInMs); } catch (Exception exception) { loggingMessage += "Failed: "; IOLogger.LogError(loggingMessage + exception.Message); } } 

您可以使用sleepTimeInMs和/或maxRetries 。 我选择了这些值,因为它们似乎足以满足任何所需的用例。

汉斯的回答取代了这个; 我将其留给上下文和仅供参考。


完成后需要关闭端口。 在尝试打开另一个句柄之前,垃圾收集器没有收集第一个SerialPort对象。 更改此代码:

 SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One); port.Open(); port.Write(reader.ReadElementContentAsString() + ","); 

至:

 using (SerialPort port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One))) { port.Open(); port.Write(reader.ReadElementContentAsString() + ","); }