SerialPort + CF 2.0可防止丢失数据

时间:2009-04-21 21:34:00

标签: c# .net compact-framework serial-port

任何人都可以告诉我为什么下面的代码会丢失或丢失数据。我一直在谷歌搜索,但找不到任何指针。串口使用以下设置; 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);
        }
    }

3 个答案:

答案 0 :(得分:1)

一些潜在的问题(不是说它们是问题,但它们会给我带来危险信号)是:

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

您可以坚持在serialPort1_DataReceived调用中假脱机数据。如果您可以保证串行链接中活动的“停机时间”,则直到您知道何时启动,然后启动处理。

E.g。数据最多可达X个字节/字符。然后另一组字符将不会进入500毫秒。然后,你有500毫秒来处理收到的字节。