Thread.Sleep() 后的 SerialPort ReadLine() 变得疯狂

发布于 2024-10-09 02:22:58 字数 1846 浏览 0 评论 0原文

我已经为这个问题奋斗了一天,但找不到答案。 我正在尝试通过 Compact Framework C# 中的 COM 端口从 GPS 设备读取数据。我正在使用 SerialPort 类(实际上是我自己的 ComPort 类装箱 SerialPort,但它只添加了我需要的两个字段,没什么特别的)。

无论如何,我在一个单独的线程中运行 while 循环,该线程从端口读取行,分析 NMEA 数据,打印它们,捕获所有异常,然后我睡眠(200)该线程,因为我需要 CPU 用于其他线程...没有睡眠它工作正常,但使用 100% CPU.. 当我几分钟后不使用睡眠时,COM 端口的输出如下所示:

GPGSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
GSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
A,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,18,12,271,24,24,05,020,24,14,04,326,25,11,03,023,*76
A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F

,您可以看到同一条消息被阅读了几次,但被剪切。 我想知道我做错了什么... 我的端口配置:

port.ReadBufferSize = 4096;  
port.BaudRate = 4800;  
port.DataBits = 8;  
port.Parity = Parity.None;  
port.StopBits = StopBits.One;  
port.NewLine = "\r\n";  
port.ReadTimeout = 1000;  
port.ReceivedBytesThreshold = 100000; 

和我的阅读功能:

private void processGps(){  
    while (!closing)   
    {  
        //reconnect if needed
        try  
        {  
            string sentence = port.ReadLine();  
            //here print the sentence  
            //analyze the sentence (this takes some time 50-100ms)  
        }  
        catch (TimeoutException)  
        {  
            Thread.Sleep(0);  
        }  
        catch (IOException ioex)  
        {  
            //handling IO exception (some info on the screen)  
        }  
    Thread.Sleep(200);  
    }  
}

该功能中还有一些其他内容,例如设备丢失时重新连接等,但当 GPS 正确连接时不会调用它。我正在尝试

port.DiscardInBuffer();

一些代码块(在 TimeoutException 中,阅读后)。

有人遇到过类似的问题吗?我真的不知道我做错了什么。获得它的唯一方法是删除最后一个睡眠。

I've been fighting with this issue for a day and I can't find answer for it.
I am trying to read data from GPS device trough COM port in Compact Framework C#. I am using SerialPort class (actually my own ComPort class boxing SerialPort, but it adds only two fields I need, nothing special).

Anyway, I am running while loop in a separate thread which reads line from the port, analyze NMEA data, print them, catch all exceptions and then I Sleep(200) the thread, because I need CPU for other threads... Without Sleep it works fine, but uses 100% CPU.. When I don't use Sleep after few minutes the output from COM port looks like this:

GPGSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
GSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
A,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,18,12,271,24,24,05,020,24,14,04,326,25,11,03,023,*76
A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F

as you can see the same message is read few times but cut.
I wonder what I'm doing wrong...
My port configuration:

port.ReadBufferSize = 4096;  
port.BaudRate = 4800;  
port.DataBits = 8;  
port.Parity = Parity.None;  
port.StopBits = StopBits.One;  
port.NewLine = "\r\n";  
port.ReadTimeout = 1000;  
port.ReceivedBytesThreshold = 100000; 

And my reading function:

private void processGps(){  
    while (!closing)   
    {  
        //reconnect if needed
        try  
        {  
            string sentence = port.ReadLine();  
            //here print the sentence  
            //analyze the sentence (this takes some time 50-100ms)  
        }  
        catch (TimeoutException)  
        {  
            Thread.Sleep(0);  
        }  
        catch (IOException ioex)  
        {  
            //handling IO exception (some info on the screen)  
        }  
    Thread.Sleep(200);  
    }  
}

There is some more stuff in this function like reconnection if the device is lost etc., but it is not called when the GPS is connected properly. I was trying

port.DiscardInBuffer();

after some blocks of code (in TimeoutException, after read.)

Did anyone had similar problem? I really dont know what I'm doing wrong.. The only way to get rig of it is removing the last Sleep.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

安穩 2024-10-16 02:22:58

对于所有有类似问题的人。第一个问题是关于缓冲区溢出。我有 4096 大小的缓冲区,数据只是流过它,所以我正在读取损坏的句子。现在我一次读取所有缓冲区并对其进行分析。第一句话有时会损坏,但其余的都可以。
第二件事是设备问题。 Tom Tom MkII 有时会与设备失去连接。我不得不重新启动 GPS 并在 Bt 设备列表中再次找到它。
问候

For all those who have similar problem. The first issue was about overflowing the buffer. I had 4096 size of buffer and the data was just flowing trough it so I was reading corrupted sentences. Now I read all buffer at once and analyze it. First sentence is sometimes corrupted, but the rest is ok.
The second thing was the device issue. Tom Tom MkII sometimes loses connection with the device. I had to restart the GPS and find it again in Bt devices list.
Regards

染火枫林 2024-10-16 02:22:58

您的帖子中没有任何内容说明您如何握手。

通常您会使用软件(XON/XOFF)或硬件(例如RTS/CTS)握手,以便串口在无法接收更多数据时告诉停止发送。当然,握手配置必须与发送设备的配置相匹配。

如果您未能正确配置握手,只要您处理数据的速度足够快,您就可能逃脱惩罚 - 但当您处于睡眠状态时,数据可能会丢失。

There's nothing in your post to say how you are doing handshaking.

Normally you would use software (XON/XOFF) or hardware (e.g. RTS/CTS) handshaking so that the serial port will tell the transmitting to stop when it is unable to receive more data. The handshaking configuration must (of course) match the configuration of the transmitting device.

If you fail to configure handshaking correctly, you may get away with it as long as you are processing the data fast enough - but when you have a Sleep, data may be lost.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文