线程睡眠阻塞串口数据事件处理器

thread sleep blocking serial port data event handler

我正在通过工作正常的串口读取数据。以下是我的简短代码

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 时,我收到不到 1000 字节,直到 thread.sleep 语句之后,但是如果我在 thread.sleep 步骤设置断点,我收到完整的 2000字节。那么 thread.sleep(background thread) 是否也阻塞数据接收事件处理程序?我怎样才能避免这个问题?

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

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

处理串行输入的最佳方法是使用 SerialPort class 的已经异步的 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 字节足够快,您甚至根本不需要生成新线程。