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

C# 串行端口+;CF 2.0防止数据丢失,c#,.net,compact-framework,serial-port,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)

有人能告诉我为什么下面的代码会丢失或删除数据吗。我在谷歌上搜索了一整夜,但找不到任何指针。串行端口正在使用以下设置;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);
        }
    }

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

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

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

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

您可以坚持在serialPort1_DataReceived调用中假脱机数据。如果您可以保证串行链接中的活动处于“停机时间”,请先关闭spool,直到您知道何时将停止处理


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

谢谢Chris,我在锁块中的处理代码中也尝试了同样的方法。但那没用。在你看来,我应该使用锁(syncObject)以外的东西吗?我只是在找STX和ETX,它们应该属于ASCII编码,不是吗?丢失的数据只发生在较大的文件上,我正在测试的文件大约是484Kb,它实际上是文件中间的奇数个字符。代码似乎总是拾取stx/etx ok。谢谢Chris,我在锁块中处理代码时也尝试了同样的方法。但那没用。在你看来,我应该使用锁(syncObject)以外的东西吗?我只是在找STX和ETX,它们应该属于ASCII编码,不是吗?丢失的数据只发生在较大的文件上,我正在测试的文件大约是484Kb,它实际上是文件中间的奇数个字符。代码似乎总是拾取stx/etx ok