Visual C# SerialPort Event Handler

OP #5154302
Nabend,

ich möchte gerne auf Eingehende Bytes reagieren und diese speichern.
Die Messagebox erscheint zwar mit den ankommenden Daten, dass Programm 
hängt sich aber auf sobald es den Eingehenden String in die TextBox 
schreiben soll.

Wie kann ich das umgehen?
1
        void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
2
        {
3
            SerialPort localPort = (SerialPort)sender;
4
            uartInput = localPort.ReadExisting();
5
            saveReceivedData(this,uartInput);
6
        }
7

8
        void saveReceivedData(object sender, string input)
9
        {
10
            MessageBox.Show(input);
11
            this.uartMessageBox.Text = input;
12
        }
Gast
Felix U. schrieb:
> Könnte sein, dass die MessageBox den Thread zu lange blockiert.
> Kommentiere die Messagebox mal aus.

Das sollte sie eben nicht, da sie ja auf keine Antwort wartet.
Ansonsten den Empfangsstring per delegate in eine Listbox oder so 
eintragen.
Gast
dunno.. schrieb:
> Vermutlich läuft die empfangsroutine nicht im ui context.

Genau - so ist es.

DataReceived der SerialPort-Klasse wird in einem eigenen Thread 
aufgerufen, nicht im typischen UI-Thread.
Windows-Forms Controls müssen aber in der Regel aus dem Thread heraus 
aktualisiert werden, von dem aus sie auch erstellt wurden. Dafür haben 
die betreffenen Controls ein InvokeRequired-Property um mitzuteilen, ob 
Invoke nötig ist.

Versucht man trotzdem vom falschen Thread aus zu updaten wird häufig 
eine Exception ausgelöst, die Frickler gerne via 
CheckForIllegalCrossThreadCalls=false einfach deaktivieren, statt kurz 
zu recherchieren was es damit auf sich hat ;D
OP
dunno.. schrieb:
> Vermutlich läuft die empfangsroutine nicht im ui context.
>
> Die messagebox ist Aber ui context, das funktioniert so nicht.
>
> Dispatcher.invoke ist das zauberwort.
>
> 
https://stackoverflow.com/questions/1644079/change-wpf-controls-from-a-non-main-thread-using-dispatcher-invoke

Okay. Wie wende ich das jetzt konkret auf meine Funktion an? Bin noch 
ziemlich unerfahren. Kannst du mir das mal anhand meines Problems 
schildern?
Da wäre ich dir endlos dankbar.
Gast
Eine kompakte Variante wäre:
1
void saveReceivedData(object sender, string input)
2
{
3
    this.uartMessageBox.Invoke(() => {
4
       MessageBox.Show(input);
5
       this.uartMessageBox.Text = input;
6
    });
7
}
...durch das Invoke() wird quasi für den angegebenen Code auf den Thread 
zu dem uartMessageBox gehört gewechselt und dort der Code ausgeführt.
(siehe auch: https://stackoverflow.com/a/253150/3408300)

In deiner
1
void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
würde ich außerdem noch e.EventType abfragen, siehe dazu das potentielle 
Deadlock-Problem mit EoF hier: 
https://stackoverflow.com/a/13438355/3408300
OP
bluppdidupp schrieb:
> Eine kompakte Variante wäre:
>
1
> void saveReceivedData(object sender, string input)
2
> {
3
>     this.uartMessageBox.Invoke(() => {
4
>        MessageBox.Show(input);
5
>        this.uartMessageBox.Text = input;
6
>     });
7
> }
8
>
> ...durch das Invoke() wird quasi für den angegebenen Code auf den Thread
> zu dem uartMessageBox gehört gewechselt und dort der Code ausgeführt.
> (siehe auch: https://stackoverflow.com/a/253150/3408300)
>
> In deiner
1
void DataReceivedHandler(object sender, 
2
> SerialDataReceivedEventArgs e)
> würde ich außerdem noch e.EventType abfragen, siehe dazu das potentielle
> Deadlock-Problem mit EoF hier:
> https://stackoverflow.com/a/13438355/3408300


Danke erstmal für die Erklärung.
Leider klappt das nicht? Er sagt mir folgendes.. (siehe Bild)
Angehängte Dateien:

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.