【问题标题】:Application freezes during SerialPort.Open() - GPS module应用程序在 SerialPort.Open() 期间冻结 - GPS 模块
【发布时间】:2014-08-21 07:05:05
【问题描述】:

我正在编写一个应用程序,它检查机器中是否安装了 (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;
}

【问题讨论】:

  • 这是否发生在您的主应用程序线程上?
  • 不,它没有。我的 Main Application 线程是我的 MainForm,它在一个线程中启动上面的函数(写在一个 DLL 中)。
  • 当系统死机时,你能不能在visual studio中暂停执行,看看你在代码中的什么位置?
  • 不,我不能,Visual Studio 也会冻结。关闭和打开 gps 模块(通过 GPIO)将使视觉工作室恢复活力。
  • 我可以看到(在控制台中)“Opening COM8 @ 4800 Baud”并且下一个字符“*”已经丢失。所以我猜它只能是 SerialPort.Open() 方法。

标签: c# gps serial-port


【解决方案1】:

Here 是其他人遇到了 SerialPort.Open 挂起一段时间的问题。他们建议在新线程上启动每个 SerialPort.Open 并在一段时间后将其终止。

这还有一个额外的好处,就是让您可以同时打开每个串行端口。如果您有 3 个 com 端口,则您的代码的最坏情况执行时间为 36 秒。在单独的线程上同时执行 3 个端口中的每一个会将其降低到最坏的情况下 12 秒。

【讨论】:

  • 好吧,现在我(偶尔)在 System.dll 中得到一个 System.UnauthorizedAccessException" instat '*'-Char
【解决方案2】:

我遇到了同样的问题,使用SerilaPort.Dispose() 并重试SerialPort.Open() 后它消失了。看起来我的程序没有释放上一个会话的端口资源,所以当我尝试再次打开它时它挂起。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2014-07-18
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    相关资源
    最近更新 更多