SerialPort UnauthorizedAccessException

pro*_*ach 10 c# serial-port

有时我的某些集成测试会因上述消息而失败.我正在使用下面的代码来准备端口.

            for(int i = 0; i < 5; i++)
            {
                try
                {
                    port.Open();
                    if (port.IsOpen)
                        break;
                }
                catch (Exception e)
                {
                    try
                    {
                        port.Close();
                    }
                    catch (Exception)
                    {}
                    Thread.Sleep(300);
                }
            }   
Run Code Online (Sandbox Code Playgroud)

我的假设是,因为它不能阻止端口的当前线程(因为它会尝试关闭它),它必须是另一个线程或进程已经死亡而没有正确清理(其他测试之一 - 没有其他访问这个港口).有没有办法重置状态,SerialPort以便新线程/进程可以再次访问它?

谢谢,

理查德

Han*_*ant 16

这是SerialPort类中的一个缺陷,它使用内部帮助程序线程来等待端口上的事件.DataReceived,PinChanged和ErrorReceived事件的来源.该缺陷在Close()方法实现中,它不等待这个辅助线程终止.这需要时间,确切的时间量是不可预测的,并且当机器特别繁忙时可能需要很多秒.在发生这种情况之前,物理端口不会关闭,在线程退出炸弹之前打开端口并使用"已在使用的端口"例外.你得到的那个.因此,睡眠300毫秒是不够的.

这通常不是问题,串口不是可共享的设备.关闭串口而不退出程序是危险的,另一个进程可能会窃取端口.当您尝试再次打开它时也会给您这个例外.通常的做法是在应用程序启动时打开端口,而不是关闭它直到它终止.


ski*_*les 5

我通常在实例化串行端口之前先验证端口是否已关闭。如果您在不关闭串行端口的情况下停止调试代码,则将有帮助。另外,在打开或关闭端口之后,您应该等待250毫秒,然后再继续执行代码。

try
        {
            if ((m_SerialPort != null))
            {
                if (m_SerialPort.IsOpen)
                {
                    m_SerialPort.Close();
                }
             }
             m_SerialPort = new SerialPort(portName, dataRate, parity, databits, stopBits.One);
             m_SerialPort.Open();
             if (!m_SerialPort.IsOpen)
             {
                 MessageBox.Show(string.Concat(portName, " failed to open"));
             }
         }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
Run Code Online (Sandbox Code Playgroud)