Forum: PC-Programmierung [.Net] Ungültiger threadübergreifender Vorgang - Visual Studio 2017


von skorpionx (Gast)


Angehängte Dateien:

Lesenswert?

Ich schreibe unter Visual Studio 2017 ein Programm für
Serielle Schnittstelle. Empfang funktioniert ohne Fehler
wenn ich Daten in einen lokalen String schreibe. Ich versuche
aber die Daten (für Visualisierung)  in textBox zu schreiben.
Aber das bringt den Fehler:
„Ungültiger threadübergreifender Vorgang“

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du schreibst nicht "unter Visual Studio 2017", sondern Du schreibst in 
einer .Net-Sprache.

Das ist für die Fehlersuche wichtig.

Du hast offensichtlich (mindestens) zwei Threads, und versuchst aus 
einem Thread auf ein Objekt zuzugreifen, das einem anderen Thread 
gehört.

Das ist nicht zulässig.

https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls

von c-hater (Gast)


Lesenswert?

skorpionx schrieb:

> Ich schreibe unter Visual Studio 2017 ein Programm für
> Serielle Schnittstelle. Empfang funktioniert ohne Fehler
> wenn ich Daten in einen lokalen String schreibe. Ich versuche
> aber die Daten (für Visualisierung)  in textBox zu schreiben.
> Aber das bringt den Fehler:
> „Ungültiger threadübergreifender Vorgang“

Die Ereignisse von SerialPort erfolgen nicht im Kontext des 
Haupt-Threads des Programmes, der für das GUI zuständig ist. Deswegen 
haben nahezu alle GUI-Komponenten eine eingebaute Warnung, denn das GUI 
ist nicht threadfest, es würde also unkontrollierbare Scheisse 
passieren, wenn es diese Warnung nicht gäbe.

Um zu erreichen, was du willst, mußt du (etwas vereinfacht) das Ereignis 
des fremden Threads in den Kontext deines GUI-Threads zwingen. Dafür 
bieten die allermeisten GUI-Komponenten (als Erben von Control) 
freundlicherweise die passenden Methoden an, nämlich:

InvokeRequired
Invoke
BeginInvoke

Wenn du nach diesen Methoden googelst, wirst du sicher den Code 
hunderter Anwendungsfälle finden.

Aber Vorsicht: Viele davon sind nicht ganz korrekt, was zu Problemen 
(besonders beim Start oder beim Beenden der Anwendung) führen kann. 
Schuld sind meiner Meinung nach daran aber nicht die Verfasser der 
entsprechenden Code-Stellen, sondern allein Microsoft. Das Problem ist 
nämlich, dass InvokeRequired NICHT tut, was man von einer Methode 
dieses Namens erwarten könnte. Die hätte eigentlich heissen müssen: 
InvokeRequiredAndPossible und müsste ein Ergebnis liefern, anhand dessen 
man zwischen den drei relevanten Situationen unterscheiden kann...

von Matthias S. (da_user)


Lesenswert?

Such die Fehlermeldung mal bei mycsharp, da gibt's ein gutes Howto.

von Frank L. (Firma: Flk Consulting UG) (flk)


Lesenswert?

Hallo,
wie schon oben beschrieben, musst Du das Ganze synchronisieren.
1
        private delegate void DoEnableGuiDelegate(bool enable);
2
        private void DoEnableGuiExcute(bool enable)
3
        {
4
            UpdateCommands();
5
        }
6
7
        private void DoEnableGui(bool enable)
8
        {
9
            if (InvokeRequired)
10
            {
11
                Invoke(new DoEnableGuiDelegate(DoEnableGuiExcute), enable);
12
                return;
13
            }
14
            DoEnableGui(enable);
15
        }

Ich löse das in der Regel so, DoEnableGui wird vom Event aufgerufen. 
Hier wird geprüft, ob ein InvokeRequired notwendig ist, wenn ja, wird 
der Delegate erzeugt und die Methode rekursiv aufgerufen.

Funktioniert sauber und zuverlässig.

Die Implementierung erfolgt in dem Form, in dem die Ausgabe bzw. wie bei 
mir die Buttons enabled oder disabled werden sollen.

Gruß
Frank

von skorpionx (Gast)


Lesenswert?

Es funktioniert. Mein erster Kontakt mit delegate und Invoke …
Es war ziemlich mühsam. Das was man beim googeln finden muss
man gut „filtern“.Außerdem hilft so genannte „intuitive 
Programmierung“...

von c-hater (Gast)


Lesenswert?

skorpionx schrieb:

> Es funktioniert. Mein erster Kontakt mit delegate und Invoke …

So what? Jeder fängt irgendwann mal an.

> Es war ziemlich mühsam.

So what? Jeder Anfang ist mühsam.

> Das was man beim googeln finden muss
> man gut „filtern“.

Natürlich. Das Problem ist nur: wenn man von einer Sache wirklich 
absolut keine Ahnung hat, kann man eben nicht wirklich einschätzen, was 
man besser filtern sollte...

> Außerdem hilft so genannte „intuitive
> Programmierung“...

Was genau meinst du damit? Ich neige bis zu einer Erklärung eher dazu, 
dass du nicht wirklich kapiert hat, was du tust, dass es aber irgendwann 
mehr oder weniger zufällig geklappt hat. Dann kann ich dir schon 
vorhersagen, dass die kleinste Änderung im Code dafür sorgen wird, dass 
wieder Scheisse passiert...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.