1

我正在从串行端口接收数据,将每一行放入队列中,然后将这些行出列,稍微格式化它们(删除一些前导字符,修剪等),然后在列表框中显示格式化的行。

我使用 Timer 每 200 毫秒触发一次出队方法。一切正常,但似乎有点迟钝/缓慢。

我正在考虑使用 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);
}
4

1 回答 1

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();
}
于 2011-12-03T16:07:01.953 回答