应用程序在SerialPort.Open() - GPS模块期间冻结

时间:2014-08-21 07:05:05

标签: c# gps serial-port

我正在编写一个应用程序,用于检查(ublox)GPS模块是否安装在机器中,如果是,则通过串行接口读取数据。我不知道模块在哪个端口工作,因此程序会检查所有COM端口是否有4800和9600波特的输入信号。

Ublox GPS模块实际上适应波特率(4800或9600)。

应用程序经常在搜索过程中冻结,关闭和关闭GPS模块再次解决了这个问题。打开GPS模块所连接的COM端口后,偶尔会出现问题。

我为SerialPort提供了一个ReadTimeout,但是在错误屏幕中没有做任何更改。

public static List<GPSDevicePort> DetectGPSSerialPorts()
{
    List<GPSDevicePort> ret = new List<GPSDevicePort>();
    List<int> baudrates = new List<int> { 4800, 9600 };

    foreach (string portName in SerialPort.GetPortNames())
    {
        foreach (int br in baudrates)
        {
            try
            {
                bool detected = false;

                using (SerialPort port = new SerialPort(portName, br))
                {
                    port.ReadTimeout = 1000;
                    port.DtrEnable = true;

                    // Auf GPS Daten warten...
                    Console.Write(string.Format("Opening {0} @ {1} Baud", portName, br));
                    port.Open();

                    int i = 0;
                    while(i < 5)
                    {
                        Console.Write("*");
                        string s = port.ReadExisting();

                        if (s.Contains("$GP"))
                        {
                            Console.WriteLine(string.Format("***[{0}@{1}]: {2}", portName, br, s));

                            GPSDevicePort devInfo = new GPSDevicePort(portName, port.BaudRate);
                            ret.Add(devInfo);

                            detected = true;
                            break;
                        }

                        i++;
                    }

                    Console.WriteLine("");
                    port.Close();
                    port.Dispose();
                }

                Thread.Sleep(1000);

                if (detected)
                    break;
            }
            catch (Exception ex) {}
        }
    }

    return ret;
}

2 个答案:

答案 0 :(得分:0)

Here是其他有问题的人,其中SerialPort.Open会挂起一段时间。他们建议在新线程上启动每个SerialPort.Open并在一段时间后终止它。

这还有一个额外的好处,就是让您同时打开每个串口。如果您有3个COM端口,则您的代码的最差情况执行时间为36秒。在不同的线程上同时执行3个端口中的每个端口会将其丢弃到12秒的最坏情况。

答案 1 :(得分:0)

我遇到了同样的问题,使用SerilaPort.Dispose()并重试SerialPort.Open()即可解决问题。看起来我的程序没有从前一个会话中释放端口资源,所以当我试图再次打开它时,它被挂起了。