2

こんにちは、タイミング システムからリアルタイムで仮想スコアボードに時間情報を表示する単純な C# WPF をプログラムしようとしています。私はプログラミングにかなり慣れていないので、詳細な説明をいただければ幸いです。

COM ポートからの着信データを処理する新しいスレッドを作成しました。アプリが開発されると、このデータが解釈されます。今のところ、タイマーからの生の情報 (16 進数) をテキスト ボックスに表示したかっただけです。これは機能しますが、意図したとおりではありません。大量の重複した情報を受け取っています。私の唯一の説明は、データの読み取りが遅すぎるか、同じバイトを何度も読み取っているということです。私がやりたいことは、各バイトを取り出して表示し、すべて 1 つの開始/停止ボタンで制御することです。

可能な解決策には、バッファ全体をリストまたは配列に格納することが含まれますが、これはまだよくわかりません。プログラムがすべてをフリーズさせるほど多くのスレッドを追加したくありません。

これまでのコードは次のとおりです (ここに記述したほとんどすべてのコードは初めてなので、悪い習慣があれば教えてください):

public partial class MainWindow : Window
{
    SerialPort comms;
    Thread commThread;

    bool flag;
    string message;


    public MainWindow()
    {
        InitializeComponent();
        comms = new SerialPort();
    }

    private void PortControl_Click(object sender, RoutedEventArgs e)
    {
        if (!comms.IsOpen)
        {
            PortControl.Content = "Stop";
            comms.PortName = "COM1";
            comms.BaudRate = 9600;
            comms.DataBits = 8;
            comms.StopBits = StopBits.One;
            comms.Parity = Parity.Even;
            comms.ReadTimeout = 500;
            comms.ReceivedBytesThreshold = 1;

            commThread = new Thread(new ThreadStart(Handle));

            comms.Open();

            comms.DataReceived += new SerialDataReceivedEventHandler(ReadIn);
        }
        else
        {
            PortControl.Content = "Start";
            flag = false;
            comms.DataReceived -= ReadIn;

            commThread.Join();
            comms.Close();
        }
    }

    private void ReadIn(object sender, SerialDataReceivedEventArgs e)
    {
        if (!commThread.IsAlive)
        {
            flag = true;
            commThread.Start();
        }
    }

      private void Handle()
      {
          while (flag)
          {
              if (comms.IsOpen)
              {
                  try
                  {
                      message = comms.ReadByte().ToString("X2");

                      Dispatcher.BeginInvoke((Action)(() =>
                      {
                          ConsoleBox.Text += message + " ";
                      }));
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.ToString());
                  }
              }
          }
      }


}
4

1 に答える 1

1

これが1つの解決策です。

シリアル ポートは独自のスレッドでデータを受信して​​いるため、データ受信ハンドラで着信バ​​イトを読み取る必要があります。

データを読み取り、データ受信ハンドラーのスレッドセーフな FIFO リストに追加し、メイン スレッドのリストからデータを読み取ることを提案します。

ポストシリアル ポートの読み取り + スレッドまたはそれ以上の解決策を参照してください。

于 2013-06-02T20:26:10.797 に答える