Visual C# SerialPort Event Handler

OP #5154302
Lesenswert?

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 #5154386
Lesenswert?

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 #5154388
Lesenswert?

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 #5154423
Lesenswert?

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 #5155092
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren