System.TimeoutException 中的 System.IO.Ports.dll 错误

System.TimeoutException in System.IO.Ports.dll error

我编写了一个设置参数的控制台 c# 程序(我从项目->调试选项中提供了参数)我正在尝试从以太网和串行端口获取数据。

我成功设置了 args 参数,但程序在 string filename = args[4]; 超时错误 控制台突然打开 并且表现得好像它是在无限循环中bu没有循环。(读取while之前发生错误)

对于那些想阅读那些参数是什么的人; 1 = IP,[2] = 端口号,[3] = 端口名(COM3),[4] = 文件名。

[编辑] 考虑到我可能同时从以太网和串行端口的两个连接获取数据,超时是为了防止数据丢失。

我还想说添加 DataReceived += new SerialDataReceivedEventHandler(ProcessReceivedData); 而不是 while 没有任何好处,因为它再次发生在 while 循环之前。

有人知道吗?

static int Main(string[] args)
        {

            int err = 0;

            if (args.Length == 5)
            {
                IPAddress IP = IPAddress.Parse(args[1]);
                int CmdPort;
                if (int.TryParse(args[2],out CmdPort))
                {
                    string filename = args[4];//takes filename 

                    String root = @".\"; //DEFAULT EXE PATH ROOT
                    string path_combined;
                    path_combined = Path.Combine(root, filename);
                    StreamWriter sw;
                    try
                    {
                        sw = File.AppendText(path_combined);
                        p = new SPWrapper(IP, CmdPort, args[3], sw);
                        if (p.Init())
                        {
                            while (!Console.KeyAvailable)
                            {
                                p.GetMessage();
                                Thread.Sleep(100);
                            }
                            p.Close();
                        }
                        sw.Flush();
                        sw.Close();
                    }
                    catch (System.IndexOutOfRangeException ex)
                    {
                        System.ArgumentException argEx = new System.ArgumentException("File creation failed!", ex);
                        err = -2;
                        throw argEx;
                    }
                }
                else
                {
                    err = -1;
                }
            }
            if (err!=0)
            {
                Console.WriteLine("Not Enough Arguments");
                Console.WriteLine("Logger IP Port ComPort FileName");
            }
            return err;
        }//end of main

Here is my other class

 public class SPWrapper
{
    private System.IO.Ports.SerialPort CmdSerialPort;

    public DateTime lastComm = DateTime.MinValue;
    public UdpClient udpClient_Cmd;
    public volatile bool _enabled_Cmd;
    public static int Ethernet_Packet_Header_Length = 14;
    private IPAddress IP { get; set; }
    private int Cmd_Port { get; set; }
    private string SerialPortName;
    private StreamWriter swLog;
    private bool _closing = false;
    private IPEndPoint IPE_Cmd;


    private void CloseEthernet()
    {
        udpClient_Cmd?.Close();
    }

    private void CloseSerialPort()
    {
        if (CmdSerialPort.IsOpen)
        {
            CmdSerialPort.Close();
        }
    }

    public void Close()
    {
        _closing = true;
        CloseEthernet();
        CloseSerialPort();
        swLog = null;
    }

    private bool InitilizeSerialPort(string portName)
    {
        try
        {
            CmdSerialPort.PortName = portName;
            CmdSerialPort.BaudRate = 115200;
            CmdSerialPort.ReadTimeout = 10; // 10milisecond read timeout

            CmdSerialPort.Open();
            if (CmdSerialPort.IsOpen)
            {
                return true;
            }
            return false;
        }
        catch (UnauthorizedAccessException e)
        {
            Debug.WriteLine(e.ToString());
            Debug.WriteLine(e.Message);
            return false;
        }
        catch (ArgumentOutOfRangeException e)
        {
            Debug.WriteLine(e.ToString());
            Debug.WriteLine(e.Message);
            return false;
        }
        catch (ArgumentException e)
        {
            Debug.WriteLine(e.ToString());
            Debug.WriteLine(e.Message);
            return false;
        }
    }

    private bool InitializeEthernet()
    {
        bool retVal = true;
        IPE_Cmd = new IPEndPoint(IP, Cmd_Port);
        try
        {
            udpClient_Cmd = new UdpClient();
            udpClient_Cmd.Client.Bind(IPE_Cmd);
            udpClient_Cmd.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 10);
        }
        catch (Exception ex)
        {
            retVal = false;
            udpClient_Cmd?.Close();
            udpClient_Cmd = null;
            Debug.WriteLine(ex.ToString());
            Debug.WriteLine(ex.Message);
            Debug.WriteLine(ex.InnerException?.ToString());
        }
        return retVal;
    }

    public SPWrapper(IPAddress ip, int cmdPort, string comPort, StreamWriter sw)
    {
        IP = ip;
        Cmd_Port = cmdPort;
        SerialPortName = comPort;
        swLog = sw;
        CmdSerialPort = new SerialPort();
    }

    public bool Init()
    {
        return (InitializeEthernet() && InitilizeSerialPort(SerialPortName));
    }

    internal void GetMessage()
    {
        lastComm = DateTime.Now;
        string SerialMessage = "";
        try
        {
            SerialMessage = CmdSerialPort.ReadLine();
        }
        catch (TimeoutException)
        {
        }
        if (SerialMessage.Length >0)
        {
            SerialMessage = SerialMessage.Trim(' ').Trim('\n').Trim('\r');
            swLog.WriteLine($"{CmdSerialPort.PortName}\t{lastComm}\t{SerialMessage}");
        }
        IPEndPoint e = new IPEndPoint(IPAddress.Any, 0);
        byte[] receiveBytes = null;
        try
        {
            receiveBytes = udpClient_Cmd?.Receive(ref e);
        }
        catch (ObjectDisposedException)
        {
            udpClient_Cmd?.Close();
            udpClient_Cmd = null;
        }
        catch(SocketException)
        {
        }
        if (receiveBytes != null)
        {
            string UDP_Read_Message = System.Text.Encoding.UTF8.GetString(receiveBytes.Skip(Ethernet_Packet_Header_Length).ToArray());
            swLog.WriteLine($"{e}\t{lastComm}\t{UDP_Read_Message}");
        }
    }
}

您是否检查过以确保 args[1]args[2] 等是您认为的那样?尝试将 args[1] 更改为 args[0] 并将其余部分减少一个 args[2] -> args[1]Reference and Reference 2.

经过在评论中与您的讨论,我想我可以回答您的问题。

这个错误肯定与您怀疑的那一行没有任何关系,因为您自己已经发现了。

您收到一个 TimeoutException,这是有道理的,因为在 InitilizeSerialPort 中您将读取超时设置为 10 毫秒。这非常短,特别是考虑到您正在阅读整行,而不仅仅是几个字节。
你真的在那里使用了更大的数字。默认值为 500 毫秒,这是一个很好的时间。如果你真的需要降低,试试看,但在大多数情况下你不需要改变它。由于您正在阅读整行,因此 500 毫秒实际上很可能不够,具体取决于您每行获得的信息量。尝试一些值直到它起作用(但如果 90 就足够了,请不要将其设置为 100,给它一点空间)。

也许值得一提,超时当然是最大的。如果您指定 1000 毫秒并且读取需要 100 毫秒,它将在 100 毫秒后 return 而不是等待超时。 要解决此问题,您可以完全删除设置 ReadTimeout-属性 的行(它将使用默认值 500 毫秒),或者您自己将其设置为更高的值。

遗憾的是,对于您在上一条评论中提到的 UnauthorizedAccessException,我无法为您提供帮助,因为这在很大程度上取决于您的设置。如果您需要帮助,您应该提出一个新问题。

编辑:
顺便说一句,您在 GetMessage 中完全吞下了 TimeoutException。不要那样做。当另一个错误发生时,你已经在写一个控制台消息,所以也在那里做。 SocketException 也是如此,它只是用相同的方法被吞噬了。 永远不要吞下异常