C# 不断检查SerialPort对象,查看是否存在任何字节,如果存在,则读取字节并执行函数

C# 不断检查SerialPort对象,查看是否存在任何字节,如果存在,则读取字节并执行函数,c#,multithreading,for-loop,background,lag,C#,Multithreading,For Loop,Background,Lag,我正在与一个设备进行接口,需要一种方法来不断检查serialport是否可以读取任何字节,如果可以,我需要读取它们并执行不同的功能。由于我正在处理的项目的原因,我无法创建data_received事件。到目前为止,我有一个无限for循环在一个新线程中运行,但它导致计算机速度减慢 有人有其他想法吗?感谢您的帮助。下面是我当前使用的for循环代码 void bw_DoWork(object sender, DoWorkEventArgs e) { object[] param

我正在与一个设备进行接口,需要一种方法来不断检查serialport是否可以读取任何字节,如果可以,我需要读取它们并执行不同的功能。由于我正在处理的项目的原因,我无法创建data_received事件。到目前为止,我有一个无限for循环在一个新线程中运行,但它导致计算机速度减慢

有人有其他想法吗?感谢您的帮助。下面是我当前使用的for循环代码

void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        object[] parameters = (object[])e.Argument;
        SerialPort port = (SerialPort)parameters[0];
        agentRadio agentR = (agentRadio)parameters[1];

        for (; ; )
        {
            if (port.IsOpen)
            {
                try
                {
                    if (port.BytesToRead > 0)
                    {
                        byte value = (byte)port.ReadByte();

                        if (value == Global.OFF_CHAR)
                        {
                            port.Close();
                            Global.isConnected = false;
                            Form form = new Form();
                            form.deviceDisconnect(agentR);

                            MessageBox.Show("Your device has disconnected on its own, due to inactivity or because a key was switched off.", "Device Disconnect", MessageBoxButton.OK, MessageBoxImage.Information);

                            break;
                        }
                        else if (value == Global.WARNING_CHAR[0])
                        {
                            if (Global.activeClick)
                            {
                                port.BaseStream.Write(Global.POLL_CHAR, 0, Global.POLL_CHAR.Length);
                            }
                        }
                    }
                }
                catch {  }
            }
            else
            {
                break;
            }
        }
    }

摆脱可怕的“if(port.BytesToRead>0)”轮询循环!为什么要这样做?如果检查返回false,则不执行其他操作,因此只需让读取块以正常方式执行。

使用
DataReceived
事件。此事件在次线程上调用,无需创建另一个事件,或者默认情况下,ReadTimeout属性设置为InfiniteTimeout,因此代码将位于ReadByte方法中等待数据。您看到的速度减慢可能是由于重复读取造成的(一个来自轮询,一个来自读取)。我在代码的其他地方将读取超时设置为5000毫秒,因此它不会等待任何东西,或者至少不应该等待。我不需要循环投票吗?如果没有它,它将试图在没有字节的情况下读取一个字节,并导致不必要的超时异常。“因此它不会等待任何东西”-这正是问题所在-应该是。DataReceived事件是专门为这样编写的,因此您不必像这样编写代码。删除BytesToRead测试将立即解决您的问题。我对使用data received事件的关注是,我需要一些可以暂停和恢复的内容,或者使用需要从代码的其他地方调用的不同函数进行处置/重新初始化。因为我在没有数据接收事件的情况下手动读取数千字节,如果用户单击其他按钮加载/发送设置,我需要能够随意读取;是否可以暂停并恢复接收到的数据事件,或者更改处理程序一个执行某项操作,另一个忽略所有操作?暂停并恢复从串行端口接收数据?如果这样做,就有丢失数据的风险。它可能会使缓冲区溢出,当您读取数据时,一些缓冲区可能已经丢失。您可以使用data received(数据接收)事件“暂停”,只需在接收数据时缓冲数据,并在您认为合适时(即恢复时或暂停前)处理该缓冲区即可。