Laden...

Stillstand beim Lesen vom Seriellen Port

Erstellt von DonCarlos vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.960 Views
D
DonCarlos Themenstarter:in
19 Beiträge seit 2008
vor 16 Jahren
Stillstand beim Lesen vom Seriellen Port

Hallo,

Also ich habe mal als kleine Fingerübung die Daten von meinem GPS Empfänger ausgelesen.

Ich habe mir einen seinen Seriellen Port definiert und das Event DataRecieved befüllt.
In dem DataRecievd wird per Invoke ein Delegat aufgerufen, der den Datensatz direkt in eine Listbox schreibt.

Starten und Stoppen des Vorgangs führt über das Öffnen und Schliessen des Seriellen Ports.

Leider kommt es nun in einem kleinen Prozentsatz der Fälle dazu, dass mir die Anwendung einfriert, wenn ich den Seriellen Port stoppe.

Nach ein bischen rumprobieren habe ich auch wohl die Ursache gefunden und zwar wird wohl der Event auch nach dem Schliessen (oder während des schliessens?) aufgerufen und das gibt ein Problem....

Leider weiß ich nicht so recht wie ich das nun umgehen soll....

Ich hab zu dem Thema auch schon zu Themen zum Problem "Thread schliessen" gesucht und da Hinweise gefunden dass mir "Sync" Objekte wohl helfen könnten, allerdings habe ich da keine Ahnung wie ich das einbauen soll...

Angehängt ist das ganze Projekt.
Da es sich um ein Testprogramm handelt ist das alles nicht ganz so sauber ausprogrammiert. Die enthaltenen SleepAnweisungen sind zum Provozieren des Fehlers gedacht.

Anfangs war mein Denken, ich könnte mit SerialPort1.DiscardInBuffer alle nachfolgenden Daten und damit Events verwerfen - funktioniert leider nicht.
Nächste Idee war nicht mehr, die Sachen mit Readline sondern mit ReadExisting auszulesen - funktioniert leider auch nicht....

Vielleicht kann mir ja wer einen Hinweis geben 🙂
Danke!

S
8.746 Beiträge seit 2005
vor 16 Jahren

Du kannst nicht verhindern, das auch nach Schließen des Ports noch Events eintrudeln. Das liegt daran, dass der SerialPort die Events in eigenen Threads verschickt. Die sind dann bereits auf dem Weg, wenn du den Port schliesst. Du kannst aber im DataReceived-Event einfach SerialPort.IsOpen abfragen und dann die weitere Verarbeitung einfach verwerfen.

D
DonCarlos Themenstarter:in
19 Beiträge seit 2008
vor 16 Jahren

Hi, das mit dem IsOpen habe ich auch schon gemacht - gleicher Erfolg, sogar auf BreakState habe ich abgeprüft.... gleiches Ergebnis...

Einzige Möglichkeit das Sicher zu machen ist, beim Stoppen nur den Event zu entfernen. Dann trudeln noch zwei drei Datensätze ein und dann ists gut. Nur bleibt halt dann die Frage wann ich den Port schliessen soll. Gar nicht?!

S
8.746 Beiträge seit 2005
vor 16 Jahren

Hab mir mal deinen Code angeschaut. Du solltest im DataReceivedEvent nicht nur mit ReadLine() arbeiten, sondern mit ReadExisting(). Zudem solltest du nicht Invoke() verwenden, sondern BeginInvoke. Dann musst du noch das ReadExisting vor dem Close im UI-Thread entfernen (nicht thread-safe).

D
DonCarlos Themenstarter:in
19 Beiträge seit 2008
vor 16 Jahren

ReadExisting habe ich gestern abend glaub ich auch nochmal ausprobiert .. hat zumindest alleine nix gebracht ...

Wo ist den der Unterschied zwischen BeginInvoke und Invoke?

das Readexisting vor dem Close war auch einer meiner Versuche die Events zu stoppen - macht ja auch keinen Sinn 🙂

Danke für die Hilfe !

Edit: Hab den Unterschied von Begininvoke und Invoke schon gefunden.
Werde den ganzen Sums dann bei gelegenheit mal testen!

S
489 Beiträge seit 2007
vor 16 Jahren

Wo ist den der Unterschied zwischen BeginInvoke und Invoke?

Invoke ist synchron, BeginInvoke ist asynchron

D
DonCarlos Themenstarter:in
19 Beiträge seit 2008
vor 16 Jahren

das begininvoke hat wohl nun mein problem gelöst!

allerdings darf ich beim einlesen nicht mit readexisting arbeiten (zumindest nicht bei meiner jetzigen logik) da er da eben auch nur die hälfte einer Zeile einliest....

Aber jetzt passts 🙂