串行端口 + CF 2.0防止数据丢失

发布于 2024-07-18 07:17:27 字数 1631 浏览 2 评论 0原文

谁能告诉我为什么下面的代码会丢失或丢失数据。 我整晚都在谷歌上搜索,但找不到任何指示。 串行端口使用以下设置; 38400,n,8,1 xon/xoff 流量控制。 ReceivedBytesThreshold = 1。isReceiving

和 stockReceived 都是表单的成员

       private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string dataReceived = serialPort1.ReadExisting();
        bytecount += dataReceived.Length;
        processSerialData(dataReceived);
    }

    private void processSerialData(string dataReceived)
    {
        if (isReceiving == false)
        {
            int stxpos = dataReceived.IndexOf('\x02');
            if (stxpos != -1)
            {
                dataReceived = dataReceived.Replace("\x02", "");
                labelcaption = "Receiving... ";
                this.Invoke(new EventHandler(SetLabel));
                isReceiving = true;
            }
        }

        int etxpos = dataReceived.IndexOf('\x03');
        if (etxpos != -1)
        {
            dataReceived = dataReceived.Replace("\x03", "");
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
            tmpFile.Close();
            isReceiving = false;
            stockReceived = true;
        }

        // Now we need to write the data to file
        if (isReceiving == true)
        {
            if ((bytecount / recordSize) % 100 == 0)
            {
                labelcaption = "Receiving... " + (bytecount / recordSize);
                this.Invoke(new EventHandler(SetLabel));
            }
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
        }
    }

Can anyone tell my why the code below would be missing or dropping data. I have been googling all night but can't find any pointers. the serial port is using the following settings; 38400,n,8,1 xon/xoff flow control. ReceivedBytesThreshold = 1.

isReceiving and stockReceived are both members of the form

       private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string dataReceived = serialPort1.ReadExisting();
        bytecount += dataReceived.Length;
        processSerialData(dataReceived);
    }

    private void processSerialData(string dataReceived)
    {
        if (isReceiving == false)
        {
            int stxpos = dataReceived.IndexOf('\x02');
            if (stxpos != -1)
            {
                dataReceived = dataReceived.Replace("\x02", "");
                labelcaption = "Receiving... ";
                this.Invoke(new EventHandler(SetLabel));
                isReceiving = true;
            }
        }

        int etxpos = dataReceived.IndexOf('\x03');
        if (etxpos != -1)
        {
            dataReceived = dataReceived.Replace("\x03", "");
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
            tmpFile.Close();
            isReceiving = false;
            stockReceived = true;
        }

        // Now we need to write the data to file
        if (isReceiving == true)
        {
            if ((bytecount / recordSize) % 100 == 0)
            {
                labelcaption = "Receiving... " + (bytecount / recordSize);
                this.Invoke(new EventHandler(SetLabel));
            }
            //tmpFile.Write(dataReceived);
            writeToFile(dataReceived);
        }
    }

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

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

发布评论

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

评论(3

椒妓 2024-07-25 07:17:27

您不处理在一个 DataReceived 数据包中接收多个 STX 或 ETX 的情况。

You do not handle the case of recieving multiple STX's, or ETX's in one DataReceived packet.

终难愈 2024-07-25 07:17:27

几个潜在的问题(并不是说它们是问题,但它们对我提出了危险信号)是:

  • 您正在使用字符串,然后查找不可打印的字符数据。 在我看来,这是一个可疑的处理想法。 您应该接收字节,然后查找字节值。 谁知道底层编码会做什么,但是丢失一些字符,尤其是使用 ASCII 编码时,不会让我感到惊讶。
  • 这看起来也是一个潜在的线程问题。 当您收到 DataRecieved 事件时,您将读取数据,然后继续在接收处理程序的上下文中处理数据。 如果您在处理上一个事件时又收到另一个事件,会发生什么情况? 我敢打赌 byteCount 变量会被耗尽。 就我个人而言,我有一个线程专门用于接收数据,另一个线程用于处理数据。 至少我会在其中添加某种同步对象。

A couple potential problems (not saying they are the problem, but they raise red flags for me) are:

  • You're using a string and then looking for non-printable character data. This is a suspect processing idea IMO. You should be receiving bytes and then looking for byte values. Who know what the underlying encoding might do, but loss of some characters, especially if it's using ASCII encoding, wouldn't surprise me a bit.
  • This looks like a potential thread issue as well. When you get a DataRecieved event, you read the data and then go on and process the data in the context of the receive handler. What happens if you get another event while you're still processing the last? I'm betting the byteCount variable gets hosed. Personally I'd have a thread dedicated to receiving the data and another for processing it. At the very least I'd add some sort of synchronization object in there.
绿光 2024-07-25 07:17:27

由于serialPort1_DataReceived是一个触发事件,它只发生在主线程中。 因此它不能同时被2个线程输入。 为了证明这一点,请打印出执行线程的线程 ID (Thread.CurrentThread.ManagedThreadId)。

您可以坚持在serialPort1_DataReceived 调用中假脱机数据。 如果您可以保证串行链路中的活动有“停机时间”,请进行假脱机操作,直到您知道何时会停止处理。

例如,数据最多可达 X 字节/字符。 然后另一组字符在 500 毫秒内不会进来。 然后您有 500 毫秒的时间来处理接收到的字节。

As serialPort1_DataReceived is a triggered event, it only ever occurs in the main thread. Therefore it cannot be entered by 2 threads simultaneously. To prove it, print out the thread ID of the executing thread (Thread.CurrentThread.ManagedThreadId).

You can stick to spooling the data in the serialPort1_DataReceived call. If you can guarantee a "down-time" in activity in the serial link, spool until you know when that will be then fire off your processing.

E.g. data will come in of up to X bytes/chars. Then another set of chars won't come in for 500ms. You then have the 500ms to process the received bytes.

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