线程睡眠阻止串行端口数据事件处理程序



我正在通过串行端口读取数据,该端口工作正常。以下是我的代码

public Form1()
{
    InitializeComponent();
    //Background worker
    m_oWorker = new BackgroundWorker();
    m_oWorker.DoWork += new DoWorkEventHandler(m_oWorker_DoWork);
    m_oWorker.ProgressChanged += new ProgressChangedEventHandler(m_oWorker_ProgressChanged);
    m_oWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oWorker_RunWorkerCompleted);
    m_oWorker.WorkerReportsProgress = true;
    m_oWorker.WorkerSupportsCancellation = true;

    connectComPort.DataReceived += new SerialDataReceivedEventHandler(receiveData);
    enableDisable();
}
void m_oWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        backProcess();
        m_oWorker.ReportProgress(100);
    }
private void backProcess()
{
    //do some work
    Thread.Sleep(10000);
    if(check if 2000 bytes received)
    {
         //do some work
    }
}

backProcess() 在后台工作线程上运行,我有一个全局队列,我在其中插入从串行端口接收的字节,并在 if 循环中检查此队列。

我的问题是,当 2000 字节从另一端发送到 pc 时,直到 thread.sleep 语句之后,我收到的字节少于 1000 字节,但如果我在 thread.sleep 步骤中设置断点,我会收到完整的 2000 字节。那么thread.sleep(后台线程)是否也阻止数据接收事件处理程序?如何避免此问题?

有些事情从你的问题中没有得到很清楚,但我认为你的设计是有缺陷的。

您根本不需要后台工作线程,也不需要休眠某些线程。

处理串行输入的最佳方法是使用 SerialPort 类的异步 DataReceived 事件,每当有数据要读取时都会调用该事件(据我从您的最新编辑中可以看出,您已经在这样做了)。

然后,您可以读取现有数据,将其附加到StringBuilder(或填充最多 2000 字节的列表),并从那里启动您想要执行的任何操作。

伪代码示例为:

DataReceived event
  1. Read data (using `SerialPort.ReadExisting`)
  2. Append Data to buffer, increase total number of bytes read
  3. If number of bytes >= 2000: Spawn new thread to handle the data

顺便说一下,BackgroundWorker不是正确的工具!如果处理 2000 字节足够快,您甚至根本不需要生成新线程。

最新更新