1

シリアルポートからデータを受信し、各行をキューに入れ、行をデキューし、わずかにフォーマット (先頭の文字を削除、トリミングなど) してから、フォーマットされた行をリストボックスに表示しています。

タイマーを使用して、200 ミリ秒ごとに Dequeuing メソッドを起動しています。すべてが機能していますが、少し遅い/遅いようです。

デキューとフォーマットを処理するために BackgroundWorker を使用することを検討していますが、行き詰まっています。

FormLoad で backgroundworker を開始しようとしましたが、すぐにコードを 1 回だけ実行することに気付きました。ループを作成するためにバックグラウンド ワーカー コード内でラベルと goto を試しましたが (よくわかりません)、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 に答える