Hallo,
wenn ich versuche die Daten von einer Seriellen Schnittstelle auf zu
saugen und in eine ListBox zu schreiben, hängt sich meine Form ständig
auf.
Jan H. schrieb:> Was mache ich falsch?
keine Ahnung, was sagt der Debugger wo es hängt?
Und aus einen Event von der Seriellen Schnittstelle die GUI zu
Aktualisieren sollte gar nicht funktionieren. Dafür müsste man ein
Invoke/Delegate Methode arbeiten.
Ich glaube das ist ein gutes Stichwort.
Könnte das was damit zu tun haben?
Hier ist übrigens die Fehlermeldung.
1
{"Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement Expander_1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde."}
Peter II schrieb:> Invoke/Delegate ist das Stichwort dafür,
Alternativ geht auch diese Lösung. Ist allerdings ein bissel Pfusch...
Control.CheckForIllegalCrossThreadCalls = False
Jens P. schrieb:> Peter II schrieb:>> Invoke/Delegate ist das Stichwort dafür,>> Alternativ geht auch diese Lösung. Ist allerdings ein bissel Pfusch...>> Control.CheckForIllegalCrossThreadCalls = False
Könntet ihr mal ein Beispiel anhand meines Problems geben?
Ich steige durch die ganzen Foren im Internet schon nicht mehr durch.
Sitze schon > 9 Std. dran.
Kann doch wohl auch nicht so schwer sein.
So schwer ist das aber nicht, es gibt im Netz recht viele Anleitungen
dazu.
Control.CheckForIllegalCrossThreadCalls = False an erster Stelle im
Form_Load-Sub und du kannst normal programmieren und brauchst dir keine
Gedanken über die illegalen Thread-Calls machen. Allerdings kann man
sich damit andere Probleme einhandeln, deshalb ist diese Lösung mit
Vorsicht zu verwenden.
Jan H. schrieb:> Sehe ich das richtig, dass es dieses Beispiel ist?
nein, das zeigt nur wo das Problem entsteht.
Lies dir den Artikel durch, es hilft nicht nur Beispiel zu kopieren ohne
den Sinn zu verstehen.
GeneigterLeser schrieb:> void OnDataReceived(object sender, SerialDataReceivedEventArgs e)> {> SerialPort sp = (SerialPort) sender;> textBox1.Invoke(new UpdateCallback(this.UpdateTheTextbox),> sp.ReadExisting());> }>> void UpdateTheTextbox(string s)> {> textBox1.Text += s;> }
Ich sollte wirklich mal eine Pause machen.
Den Port schließe ich dann einfach mit
Es stürzt nach mehrmaligen Testen auch wieder ab. Die Lösungen klappen
auch nicht 100%ig.
Vill. kann das ja mal jemand Testen und findet noch einen Fehler.
Jan H. schrieb:> Es stürzt nach mehrmaligen Testen auch wieder ab.
man könnte auch mal Fehlermeldungen abfangen (Try Catch)
Vermutlich kommt jetzt ein anderen Fehler. "Stützt ab" ist keine
hilfreiche Aussage.
> Die Lösungen klappen auch nicht 100%ig.
doch machen sie, wenn man es richtig macht
das
Control.CheckForIllegalCrossThreadCalls = false;
nimmst du lieber raus, das erzeugt nur neue Fehler und hilft nicht bei
ordentlichen Programmieren.
So, und solltest du es bis morgen nicht am laufen haben, möchte ich dir
den durchaus gut gemeinten rat geben, es erstmal in vb.net zu versuchen.
dafür gibt es nochmal mehr beispiele zu diesem thema, die SOFORT
funktionieren.
ausserdem ist die sprache für absolute anfänger leichter zu verstehen.
wobei es hier ja nun ein grundlegendes problem gibt, das du erstmal
analysieren und verstehen solltest.
GeneigterLeser schrieb:> So, und solltest du es bis morgen nicht am laufen haben, möchte ich dir> den durchaus gut gemeinten rat geben, es erstmal in vb.net zu versuchen.
nein.
Es ja nur der Syntax anders, das verhalten ist identisch zu C#. Es macht
für diesen Problem überhaupt keine Sinn auf VB zu gehen. VB macht nur
für Leute sinn die vorher auch VB gemacht haben.
Die Hauptsprache für .net ist C# dafür findet man auch die meisten
Einträgen in Foren.
VB entspricht von Syntax keiner der große Programmiersprachen, da ist
immer alles anders. Damit kann man das Wissen nirgends mehr verwenden.
> Es ja nur der Syntax anders, das verhalten ist identisch zu C#.
Korrekt.
> VB entspricht von Syntax keiner der große Programmiersprachen, da ist> immer alles anders. Damit kann man das Wissen nirgends mehr verwenden.
Mir scheint hier nunmal ein leidlich begabter c&p "programmierer" am
werk zu sein, da wird es kaum schaden, wenn er eine sprache benutzt, die
für ihn leichter verständlich ist.
zum lernen der absoluten basics halte ich vb immernoch für tauglich.
nebenbei lernt er die strukturen des .net kennen, was viel wichtiger
ist.
wenn er dann erste erfolgserlebnisse hatte, kann er ja immernoch auf c#
portieren und dabei weiter lernen.
Habt ihr euch denn überhaupt mal mein Programm angeschaut und gestartet
bevor ihr hier Urteilt?
Mich würde mal interessieren, warum das so nicht klappt. Habe mich wie
oben beschrieben ( GeneigterLeser: zitierter Code ) eigentlich dran
gehalten.
Klar muss ich noch viel lernen bevor ich C# einigermaßen kann.
Darum frage ich hier auch mal vorsichtig nach.
Würde mich echt freuen, wenn ihr euch das Programm mal anschaut und mir
nen Tipp gibt, warum dies immer noch nach wie vor hängen bleibt.
Jan H. schrieb:> Habt ihr euch denn überhaupt mal mein Programm angeschaut und gestartet> bevor ihr hier Urteilt?
ja
> Mich würde mal interessieren, warum das so nicht klappt. Habe mich wie> oben beschrieben ( GeneigterLeser: zitierter Code ) eigentlich dran> gehalten.
der vorschlag war aber nicht gut. Es ist nicht ohne Grund abgeschaltet.
> Würde mich echt freuen, wenn ihr euch das Programm mal anschaut und mir> nen Tipp gibt, warum dies immer noch nach wie vor hängen bleibt.
wie schon geschrieben, es Programm bleibt nicht ohne Grund hängen. Wenn
ja dann muss du uns die Zeile nennen wo es hängt.
Und eine Fehlerbehandlung fehlt immer noch.
Peter II schrieb:>> Mich würde mal interessieren, warum das so nicht klappt. Habe mich wie>> oben beschrieben ( GeneigterLeser: zitierter Code ) eigentlich dran>> gehalten.> der vorschlag war aber nicht gut. Es ist nicht ohne Grund abgeschaltet.
Dieser Vorschlag ist nicht gut? Glaube du meinst wohl das mit dem
ausschalten der Prüfung?!
Jan H. schrieb:> Dieser Vorschlag ist nicht gut? Glaube du meinst wohl das mit dem> ausschalten der Prüfung?!
der code sieht auf den ersten Blick gut aus.
Was passiert nun. Kommt eine Fehlermeldung und "hängt" das Programm?
Wenn eine Fehlermeldung kommt, bei welcher Zeile und wie heißt die
Exception?
Wenn es hängt, bei welcher Zeile hängt es?
Hallo,
bin gerade erst nach hause gekommen.
Nein! Habe jetzt überall eine "try - catch" Anweisung drinn.
Leider greift diese nicht (bzgl. der Fehlermeldung) Das Programm hängt
sich auf, lässt sich nicht mehr bedienen und das wars. Keine
Fehlermeldung!
Sobald ich den Port wieder schließen will, reagiert die Form nicht mehr.
Muss ich denn noch was anderes machen, außer das Abo zu kündigen und den
Port zu schließen?
Jan H. schrieb:> Sobald ich den Port wieder schließen will, reagiert die Form nicht mehr.> Muss ich denn noch was anderes machen, außer das Abo zu kündigen und den> Port zu schließen?
dann unterbreche doch mal das Programm und schau in welcher Zeile er
hängt.
das an und abmelden brauchst du nur einmal für das Serial-Objekt zu
machen. Ich würde sogar sagen das abmelden braucht man überhaupt nicht.
Es könnte sein das du dir selber im Weg stehst.
Das Abmelden vom Event erzeugt eventuell noch ein letzen Event. Was dann
wiederum die GUI ansprechen will. Das geht aber nicht weil du noch der
Funktion button1_Click_1 drin bist.
Peter II schrieb:> das an und abmelden brauchst du nur einmal für das Serial-Objekt> zu> machen. Ich würde sogar sagen das abmelden braucht man überhaupt nicht.>> Es könnte sein das du dir selber im Weg stehst.>> Das Abmelden vom Event erzeugt eventuell noch ein letzen Event. Was dann> wiederum die GUI ansprechen will. Das geht aber nicht weil du noch der> Funktion button1_Click_1 drin bist.
Auch wenn ich es raus nehmen mal geht es 2 - 3 mal (öffnen/schließen)
dann mal wieder nicht. Das mit dem ab Abonnieren, habe ich raus
genommen.
Peter II schrieb:> wenn du die Zeile>>> textbox1.Invoke(this.myDelegate, new Object[] {s});>> auskommentierst, hängt er dann immer noch?
Nein. Dann klappt das wunderbar. Ich sollte mal meinen Aktuellen Code
posten.
ändere es mal so ab, wie es von MS empfohlen ist.
https://msdn.microsoft.com/de-de/library/ms171728(v=vs.110).aspx> SerialPort sp = (SerialPort)sender;> Expander_1.Invoke(new UpdateCallback(this.UpdateTheTextbox), sp.ReadExisting());
SerialPort sp = (SerialPort)sender;
if (this.Expander_1.InvokeRequired)
{
Expander_1.Invoke(new UpdateCallback(this.UpdateTheTextbox),
sp.ReadExisting());
} else{
UpdateTheTextbox(sp.ReadExisting());
}
}
Peter II schrieb:> ändere es mal so ab, wie es von MS empfohlen ist.>> https://msdn.microsoft.com/de-de/library/ms171728(...>>> SerialPort sp = (SerialPort)sender;>> Expander_1.Invoke(new UpdateCallback(this.UpdateTheTextbox),
sp.ReadExisting());
>> SerialPort sp = (SerialPort)sender;> if (this.Expander_1.InvokeRequired)> {> Expander_1.Invoke(new UpdateCallback(this.UpdateTheTextbox),> sp.ReadExisting());> } else{> UpdateTheTextbox(sp.ReadExisting());> }> }
Leider ja.
Läuft auch nicht stabil :(
So, habe nochmal ein bischen in meiner Codekiste gewühlt. Das ist zwar
VB.NET, funktioniert aber einwandfrei. Ist natürlich nur ein Ausschnitt.
Mach mal ein gaaanz einfaches Form mit nur dem allernötigsten. Also dem
comport, einem connect button und ner textbox.
Comportname, etc. alles hardcoden.
Dann fügst du das hier mal ein und guckst was passiert. Evtl. musst du
ein bischen was umbennen oder löschen.
1
Dim indata As String
2
Private Sub SerialPort_DataReceived(ByVal sender As System.Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
3
indata = SerialPort1.ReadExisting()
4
Me.Invoke(New EventHandler(AddressOf DoUpdate))
5
End Sub
6
7
Public Sub DoUpdate()
8
If CheckBox1.Checked = True Then TextBox1.AppendText(TimeOfDay & vbCrLf)
Das Problem scheint ja nicht das "auslesen und schreiben" zu sein. Das
Problem entsteht erst wenn ich den COM wieder schließen möchte, dann
friert die Form ein.
Moin,
Ich bin mir nicht ganz sicher. Du verwirfst ja den alten Port nicht
richtig. Es kann durchaus sein, dass du da zwei Objekte hast, die sich
stören, weil der Garbage Collector noch nicht so schnell war.
das new kannst du dir an der Stelle sparen.
Wichtig. Du must bei dem SerialPort immer schauen, ob deine Variable
nicht grad null ist oder der Port schon belegt.
Bei .Close musst du auch noch einen Check einführen.
PS: Kleiner Hinweis am Rande:
> änder das mal inprivate void foo(object sender, EventArgs e){> if (myPort != null && !myPort.isOpen){> myPort.Open();> }> }>> das new kannst du dir an der Stelle sparen.>> Wichtig. Du must bei dem SerialPort immer schauen, ob deine Variable> nicht grad null ist oder der Port schon belegt.>> Bei .Close musst du auch noch einen Check einführen.>
nach wie vor...
Falls die Frage noch aktuell ist, zuerst würde ich eine Stringvariable
als Puffer verwenden, wenn Daten kommen, und nicht den Port an die
Textbox schicken.