我从串口接收数据,将每一行放入队列,然后对行进行排队,稍微格式化(删除一些前导字符,修剪等),然后在列表框中显示格式化的行。 / p>
我使用Timer每隔200ms触发一次Dequeuing方法。一切正常,但似乎有点迟缓/缓慢。
我正在考虑使用BackgroundWorker来处理排队和格式化但是我遇到了问题。
我尝试在FormLoad中启动backgroundworker,但很快意识到它只会运行一次代码。我尝试了一个标签并在后台工作代码中转到创建一个循环(我知道,不是很好),但这让我的CPU使用率很高,甚至没有工作。
我还尝试在我的串行接收事件中使用“backgroundWorker1.RunWorkerAsync();”,每次新数据进入时都会运行它,但会抛出“后台工作人员当前忙”异常
所以,我需要后台工作者来连续处理队列(出队)。
代码:继承我的数据收到事件,下面是我在后台工作中的代码。任何帮助非常感谢。
// Serial Data Received
private void serialPort1_DataReceived(
object sender,
System.IO.Ports.SerialDataReceivedEventArgs e)
{
RxString = serialPort1.ReadTo("\u0003");
q.Enqueue(RxString);
}
下一个代码是出列代码:
// Dequeue items, format, then display in listbox
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (q.Count == 0)
{
// do nothing if q is empty
}
else
do
{
output = (q.Dequeue().ToString());
output = output.TrimStart(new char[] { (char)02 });
output = output.TrimEnd(new char[] { (char)03 });
if (output.StartsWith("C"))
{
ClearAll();
}
else if (output.StartsWith("W98"))
{
txtTax.Text = (output.Remove(0, 5));
}
else if (output.StartsWith("W99"))
{
txtTotal.Text = (output.Remove(0, 24));
}
else
{
listOrderItems.Items.Add(output.Remove(0, 5));
listOrderItems.SelectedIndex = listOrderItems.Items.Count - 1;
}
} while (q.Count > 0);
}
答案 0 :(得分:0)
我没有看到在不同的线程中解析你的字符串的观点。它不是一个长时间运行的过程,并且由于您在后台线程中运行,似乎您忘记了Invoke
到Windows线程。这是我的解决方案,
using System.IO.Ports;
static void ParseData(ref string data)
{
data = data.TrimStart(new char[] { (char)02 });
data = data.TrimEnd(new char[] { (char)03 });
}
private void UpdateControlsWithData(string data)
{
Action action;
if(data.StartsWith("C")
{
action = () => ClearAll();
}
else if(data.StartsWith("W98"))
{
action = () => { txtTax.Text = data.Remove(0, 5); };
}
else if(data.StartsWith("W99"))
{
action = () => { txtTotal.Text = data.Remove(0, 24); };
}
else
{
action = () => {
listOrderItems.Items.Add(data.Remove(0, 5));
listOrderItems.SelectedIndex = listOrderItems.Items.Count - 1;
};
}
if(this.InvokeRequired()) this.Invoke(action);
else action();
}
private void HandleDataReceived()
{
string data = serialPort1.ReadTo("\u0003");
ParseData(ref data);
UpdateControlsWithData(data);
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
this.HandleDataReceived();
}