串口IOException

时间:2019-02-07 10:13:41

标签: c# winforms serial-port compact-framework

我在设备上使用.NET串行端口(CF 3.9)。尝试发送帧时出现以下错误:

2019-02-07 10:26:39,414 [218497034] ERROR Communication.Serial.ControlCommunication - System.IO.IOException: IOException
at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Communication.Serial.ControlCommunication.WriteFrame(FrameType frameType, Byte[] frame, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWriteWithoutDelay(Byte[] frame, Int32 delay, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWrite(Byte[] frame, Int32 delay)
at Communication.Serial.ControlCommunication.ExternalThread()
at System.Threading.ThreadHelper.ThreadStartHelper(ThreadHelper t)
at System.Threading.ThreadHelper.ThreadStartHelper()

2019-02-07 10:26:39,467 [165216466] ERROR Communication.Serial.ControlCommunication - System.IO.IOException: IOException
at System.IO.Ports.SerialStream.WinIOError(Int32 errorCode, String str)
at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace)
at System.IO.Ports.SerialPort.Open()
at Communication.Serial.ControlCommunication.WriteFrame(FrameType frameType, Byte[] frame, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWriteWithoutDelay(Byte[] frame, Int32 delay, SamplerDataAddress samplerDataAddress)
at Communication.Serial.ControlCommunication.SerialWrite(Byte[] frame, Int32 delay)
at Communication.Serial.ControlCommunication.RemoveOutput(ControlCommand command)
at Communication.Devices.ExternalLighting.ExternalLighting.SetLightingState(Boolean enabled)
at Communication.Devices.ExternalLighting.ExternalLighting.CheckState()
at Communication.Devices.ExternalLighting.ExternalLighting.Update()
at Communication.Serial.ControlCommunication.ExternalThread()
at System.Threading.ThreadHelper.ThreadStartHelper(ThreadHelper t)
at System.Threading.ThreadHelper.ThreadStartHelper()

WriteFrame方法:

    private void WriteFrame(FrameType frameType, byte[] frame, SamplerDataAddress samplerDataAddress = SamplerDataAddress.None)
    {
        try
        {
            lock (serialPort)
            {
                if (serialPort.IsOpen)
                    serialPort.Close();

                serialPort.Open();

                if (serialPort != null && serialPort.IsOpen)
                {
                    switch (frameType)
                    {
                        case FrameType.xx:
                            serialPort.RtsEnable = false;
                            byte[] versionFrame = ControlMethods.SendVersionReq();
                            serialPort.Write(versionFrame, 0, versionFrame.Length);
                            serialPort.BaseStream.Flush();
                            Thread.Sleep(10);
                            serialPort.RtsEnable = true;

                            Thread.Sleep(130);
                            if (serialPort.BytesToRead > 0)
                            {
                                byte[] received = new byte[serialPort.BytesToRead];
                                serialPort.Read(received, 0, serialPort.BytesToRead);

                                if (frame != null)
                                    log.Info("CheckFekoIOVersionAndCrcErrors frame: " + BitConverter.ToString(frame));

                                ControlMethods.EvaluateVersionResponse(received);
                            }

                            break;
                        case FrameType.xy:
                            serialPort.RtsEnable = false;
                            var countFrame = ControlMethods.GetFekoResetsCount();
                            serialPort.Write(countFrame, 0, countFrame.Length);
                            serialPort.BaseStream.Flush();
                            Thread.Sleep(10);
                            serialPort.RtsEnable = true;

                            Thread.Sleep(200);
                            if (serialPort.BytesToRead > 0)
                            {
                                byte[] response = new byte[serialPort.BytesToRead];
                                serialPort.Read(response, 0, serialPort.BytesToRead);

                                if (response != null)
                                    log.Info("CheckFekoIOVersionAndCrcErrors frame: " + BitConverter.ToString(response));

                                ControlMethods.EvaluateFekoResetsFrame(response);
                            }                                    

                            break;
                        case FrameType.xyz:
                            serialPort.RtsEnable = false;
                            serialPort.Write(frame, 0, frame.Length);
                            serialPort.RtsEnable = true;

                            if (samplerDataAddress != SamplerDataAddress.None)
                                Thread.Sleep(200);

                            if (samplerDataAddress == SamplerDataAddress.GetTemperature)
                                frameLog.Debug("WriteFrame frame sended" + BitConverter.ToString(frame));

                            SerialDataReceived(serialPort, null, samplerDataAddress);
                            break;
                    }
                    serialPort.Close();
                }
                else
                {
                    log.Info("Try to reopen serial port");

                    int serialPortOpenCounter = 0;
                    while (serialPortOpenCounter++ < 3 && !OpenSerialPort());
                }
            }
        }
        catch(Exception exc)
        {
            log.Error(exc);
        }
    }

我如何理解和解决此异常?

在应用程序通信中是多线程的,WriteFrame被几个线程访问。在我的测试设备上,所有设备都可以正常工作,但是在客户端设备(设备站在室外)上,我遇到了上述错误。

使用Rs-485。

1 个答案:

答案 0 :(得分:2)

经过更多研究后,请看一下以下内容:

http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html

引用:

  

在过渡期间如何解决?简单。致电之前   SerialPort.Open(),只需调用CreateFile即可打开串行端口   并将SetCommState的fAbortOnError设置为false。现在您可以安全地打开   串行端口,而不必担心它可能引发IOException。我有   提出了C#的示例解决方法,您可以将其用作   参考。

祝你好运!