serialport kontinuierliche Echtzeit-Daten in c#

Hallo, ich versuche ein Programm eine einfache C# - WPF, zeigt die Zeit, die Informationen auf einer virtuellen Anzeigetafel in Echtzeit auf einem timing-system. Ich bin ziemlich neu in der Programmierung so in die Tiefe Erklärung wäre willkommen.

Habe ich einen neuen thread auf, verarbeiten die eingehenden Daten vom COM-port und die app wird entwickelt, die diese Daten interpretiert werden. Für jetzt wollte ich nur die Anzeige der raw-Daten (in hex), die von dem timer in ein Textfeld. Dies funktioniert aber nicht wie gedacht. Ich erhalte Tonnen von doppelten Informationen, meine einzige Erklärung ist, die ich lese, die Daten zu langsam oder das Lesen der gleichen byte-über und über. Was ich möchte, geschehen ist, nehmen Sie jedes byte, und zeigen Sie, alle gesteuert durch ein start - /stop-Taste.

Den möglichen Lösungen gehören die Speicherung der gesamte Puffer wird in eine Liste oder ein array, die ich bin mir nicht ganz sicher, trotzdem glaube ich nicht hinzufügen möchten, so viele threads, dass das Programm friert alles.

Hier ist mein code bisher (ich bin neu auf so ziemlich alle der code, den ich hier geschrieben habe, also wenn was ist schlechte Praxis, lassen Sie es mich bitte wissen):

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());
                  }
              }
          }
      }


}
  • Ist ConsoleBox ein GUI-Control (TextEdit?) Bitte beachten Sie, dass Gui-Malerei, vor allem die Aktualisierung der text-Inhalte wie du getan hast extrem langsamer im Vergleich zu üblichen Prozessor-Aufgaben. Eine einfache Lösung ist in der Tat mit einem stringbuffer und einfach Anzeige dieser auf einem separaten timer.event.
  • Ja sorry ConsoleBox ist ein TextBox-ich weiß nicht, warum ich nannte es, dass ... Was ist das Timer-Ereignis braucht es nicht zu gehen in einem anderen thread? Nicht die Gewinde zu tauschen, die auf einem dual-core-CPU und verliere ich Daten?
  • verwenden Sie einfach ein einfaches timer-Steuerelement, und legen Sie die interval um eine Sekunde, dann während der timer-event-schreiben Sie den Inhalt Ihrer stringbuffer in das Textfeld ein. natürlich haben Sie Recht: Sie haben zu ausführen dieser Zugriff threadsicher, zum Beispiel mit beginInvoke, wie du schon in deinem code oben.
  • argh, sorry, Sie sind in wpf nicht winforms Welt! bitte verwenden Sie DispatcherTimer wie hier gezeigt: stackoverflow.com/questions/5410430/...
  • Ich habe mit winforms-Timer vor und es sieht aus wie Ihr einen ähnlichen Ansatz. Danke für Eure Hilfe!
  • Wenn Sie möchten, jede Art von anständigen Durchsatz für diesen code, dann haben Sie, um zu vermeiden, aufrufen Dispatcher.BeginInvoke() für jedes einzelne byte. Puffer, so dass Sie etwas haben, lohnt sich das aufrufen für.
  • Ja das weiß ich ich wollte nur die Informationen erhalten, die hereinkamen, richtig, bevor ich angefangen habe zu sammeln bytes für die Ziffern und so weiter. Vielen Dank für das heads-up, obwohl

InformationsquelleAutor pgwri | 2013-06-01
Schreibe einen Kommentar