【问题标题】:thread sleep blocking serial port data event handler线程睡眠阻塞串口数据事件处理程序
【发布时间】:2015-03-18 16:19:36
【问题描述】:

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

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 循环中检查此队列。

我的问题是,当从另一端向 pc 发送 2000 个字节时,我收到少于 1000 个字节,直到在 thread.sleep 语句之后,但是如果我在 thread.sleep 步骤设置断点,我收到完整的 2000 个字节。那么 thread.sleep(background thread) 也会阻塞数据接收事件处理程序吗?我怎样才能避免这个问题?

【问题讨论】:

  • 看不到backProcess与后台工作人员m_oWorker有什么关系;
  • 您只是通过使用调试器中断来增加睡眠。当调试器中断处于活动状态时,驱动程序会继续接收数据。整个方法存在严重缺陷,让您的 DataReceived 事件处理程序在接收到 2000 个字节后处理数据,没有必要让线程等待它发生。

标签: c# multithreading serial-port


【解决方案1】:

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

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

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

【讨论】:

  • 感谢您的回答我正在使用后台工作人员通过串口向设备发送命令并检查从设备接收到的数据。由于通信持续了一分钟,我不想阻塞 UI 线程,因此我使用后台工作程序与设备进行通信。
  • 这是不必要的,因为DataReceived 事件已经是异步的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 2022-01-06
  • 2011-09-30
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多