You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:25:54