为何SerialPort.DataReceived事件触发‘COM4路径访问被拒’错误?
问题分析与解决方案
第一段代码报错的原因
- 第一段代码在
while(true)循环内部重复创建SerialPort实例并调用Open()方法。第一次循环时串口成功打开,但下一次循环会立刻创建新的SerialPort对象,尝试再次打开同一个COM4端口——此时前一个SerialPort实例的系统资源还未释放,端口处于被占用状态,因此系统抛出"Access to the path 'COM4' is denied."错误。 - 本质问题:无限循环中反复申请打开同一串口,前一次连接的资源未释放就发起新的连接请求,触发系统端口占用保护机制。
第二段代码正常运行的原因
第二段代码将SerialPort的创建、配置和Open()操作放在循环外部,仅执行一次端口打开操作,后续循环仅负责读取串口数据,不会重复申请端口资源,因此无冲突问题。
基于事件驱动(第一种思路)的修正方案
要保留DataReceived事件的接收方式,只需将串口初始化、打开操作移出循环,确保仅执行一次,修改后的代码如下:
using System; using System.IO.Ports; // 串口实例放在循环外,确保仅创建一次 SerialPort serialPort = new SerialPort(); serialPort.PortName = "COM4"; serialPort.BaudRate = 9600; serialPort.Parity = Parity.None; serialPort.DataBits = 8; serialPort.StopBits = StopBits.One; serialPort.Handshake = Handshake.None; // 绑定数据接收事件 serialPort.DataReceived += SerialPortDataReceived; try { serialPort.Open(); Console.WriteLine("串口已打开,等待数据..."); // 用阻塞操作保持程序运行,避免直接退出 Console.ReadLine(); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } finally { // 程序退出时关闭串口,释放资源 if (serialPort.IsOpen) serialPort.Close(); } void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string data = sp.ReadExisting(); Console.WriteLine("Received data: " + data); }
核心修改点:
- 将串口实例化、配置、事件绑定及打开操作全部移至循环外,确保仅执行一次端口打开。
- 用
Console.ReadLine()替代原无限循环,维持程序运行状态的同时避免重复创建串口实例。 - 添加
finally块,确保程序退出时自动关闭串口,释放系统资源。
内容的提问来源于stack exchange,提问作者SeyedAli
相关产品推荐
相关产品推荐

