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

时间:2015-01-20 12:23:34

标签: c# multithreading serial-port

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

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(后台线程)也会阻塞数据接收事件处理程序吗?我该如何避免这个问题?

1 个答案:

答案 0 :(得分:2)

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

您根本不需要后台工作人员,也不需要睡一些线程。

处理串行输入的最佳方法是使用DataReceived类的已经异步SerialPort事件,只要有数据要读取就会被调用(你已经这样做了,到目前为止)正如我从你最新的编辑中所知道的那样。)

然后,您可以读取现有数据,将其附加到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个字节足够快,则根本不需要生成新线程。