c#有时会两次处理相同的串行接收字节

c# processes the same serially received byte twice sometimes

我的应用程序正在处理串行接收的字节,我注意到一个奇怪的错误。有时一个字节(总是碰巧是 0x03)会被处理 2 倍,我不知道为什么。

当我收到一个(或几个)字节时,我使用 += ReadExisting() 将它们添加到一个字符串中。这个字符串构成了我的缓冲区。后台工作人员处理字符串的所有字节,直到字符串为空。字符串的第一个元素在读入后被删除,这使得 string.Length() return 每个 while 循环周期都变小。

private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            rxBuffer += serial.ReadExisting(); // adds new bytes to buffer

            try { backgroundWorker1.RunWorkerAsync(); } catch { } // starts background worker if it is not working already.
        }


        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            while (rxBuffer.Length > 0) 
            {
                byte b = Convert.ToByte(rxBuffer[0]); // reads in the next byte    
                rxBuffer = rxBuffer.Remove(0, 1); // deletes this byte from the string

           // ... code ... does things do the UI and stuff

我确定 while 循环 2x 中有一些串行字节 运行。我在我的输出中看到了它。由于某些原因,双字节始终为 0x03。请注意,rxBuffer 在程序的其他任何地方都没有被触及。

Bullseye set at (0,2)
2:05:10  << 0x80
2:05:10  << 0x3
2:05:10  << 0x13
Bullseye set at (1,2)
2:05:10  << 0x80
2:05:10  << 0x3
2:05:10  << 0x3 <--- this one should not be there.
Bullseye set at (3,0)
2:05:10  << 0x14
2:05:10  << 0x80
2:05:10  << 0x3
2:05:10  << 0x15
Bullseye set at (3,2)
2:05:10  << 0x80
2:05:10  << 0x3
2:05:10  << 0x16
Bullseye set at (4,2)

为什么会发生这种情况,我该如何解决?跟异步字节读取和后台worker有关系吗???

对于快速且 不完善的 修复:

private readonly object _lock = new object();
private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        lock( _lock )
        {
        rxBuffer += serial.ReadExisting(); // adds new bytes to buffer
        }
        try { backgroundWorker1.RunWorkerAsync(); } catch { } // starts background worker if it is not working already.
    }


    private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        lock( _lock)
        {
        while (rxBuffer.Length > 0) 
        {
            byte b = Convert.ToByte(rxBuffer[0]); // reads in the next byte    
            rxBuffer = rxBuffer.Remove(0, 1); // deletes this byte from the string

       // ... code ... does things do the UI and stuff
       } // end while
       } // end lock

更复杂的解决方案需要有关您的 class 的更多信息以及对您的代码所做的更多更改。