我正在通过正常工作的串口读取数据。以下是我的简短代码
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(后台线程)也会阻塞数据接收事件处理程序吗?我该如何避免这个问题?
答案 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个字节足够快,则根本不需要生成新线程。