| |
VB.NET - Ein- und UmsteigerRe: Mehrere Befehle über RS232 senden/empfangen | | | Autor: Preisser | Datum: 30.06.12 20:07 |
| Hallo,
mir sind auch einige Sachen bei deinem Code aufgefallen.
Du behandelst ja das "DataReceived"-Event des SerialPorts, welches in einem anderen Thread (z.B. aus einem Thread-Pool) aufgerufen werden kann. In dem Ereignishandler jedoch benutzt du dann die Methode ReadTo(String), die wie die anderen Read()-Methoden allerdings blockieren kann (solange, dis die angegebene Zeichenfolge gelesen wurde).
Aber was passiert, wenn zuerst z.B. nur ein einziges Byte ankommt, welches nicht die angegebe Trennungszeichenfolge enthält? In dem Fall würde ja die ReadTo()-Methode blockieren. Wenn danach allerdings weitere Daten ankommen, müsste das DataReceived-Event wieder ausgelöst werden, allerdings würde sich der andere Thread immer noch in dem Eventhandler befinden. Nun könnte es z.B. passieren, dass ein weiterer Thread aus dem Threadpool verwendet wird, um das DataReceived-Event auszulösen, wobei wiederrum die ReadTo()-Methode des SerialPorts aufgerufen wird, was zu Fehlern führen könnte.
Man müsste sich den Quellcode der SerialPort-Klasse genauer ansehen, um nachvollziehen zu können, was in solchen Situationen passieren könnte, weshalb es vermutlich einfacher wäre, es gar nicht erst dazu kommen zu lassen und z.B. einfach einen anderen Thread zu starten, der in einer Schleife die ReadTo-Methode aufruft (so wie es auch in den MSDN-Beispielen zum SerialPort dargestellt ist).
Ein anderer Punkt ist, dass du eine Variable in der Form dazu benutzt, den empfangenen String zu speichern und dann im GUI-Thread wieder auszulesen. Normalerweise aber sollte man die empfangenen Daten im Aufruf der Methode übergeben, denn nur dafür werden sie ja gebraucht. Ansonsten kann es beispielsweise zu Race Conditions kommen, wenn man nicht entsprechend synchronisiert. Hier wird zwar durch die Verwendung von "Invoke" (statt "BeginInvoke") sichergestellt, dass "s" nicht vom Lesethread überschrieben werden kann, solange der GUI-Thread noch mit der Ausführung der "InListeEintragen"-Methode beschäftigt ist; trotzdem sollte man soetwas vermeiden.
Hier ein Beispiel für einen separaten Lesethread:
Private serialPortReadThread As Thread
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) _
Handles MyBase.Load
SerialPort1.Open()
'Lesethread starten
serialPortReadThread = New Thread( _
Sub()
ReadSerialPort(SerialPort1)
End Sub)
serialPortReadThread.Start()
End Sub
Private Sub ReadSerialPort(sp As SerialPort)
Try
Do While True
Dim s As String = sp.ReadTo(ChrW(13))
Invoke( _
Sub()
InListeEintragen(s)
End Sub)
Loop
Catch ex As ThreadInterruptedException
' Thread wurde interrupted.
End Try
End Sub
Private Sub InListeEintragen(s As String)
ListBox1.Items.Add(s)
If Not ok Then
SendZwei(s)
End If
End Sub
Private Sub Form1_FormClosed(sender As System.Object, e As _
System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
' Lesethread unterbrechen, sodass er beendet wird
serialPortReadThread.Interrupt()
End Sub
Beitrag wurde zuletzt am 30.06.12 um 20:14:03 editiert. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevISDN 1.0
Überwachung aller eingehender Anrufe!
Die DLL erkennt alle über die CAPI-Schnittstelle eingehenden Anrufe und teilt Ihnen sogar mit, aus welchem Ortsbereich der Anruf stammt. Weitere Highlights: Online-Rufident, Erkennung der Anrufbehandlung u.v.m. Weitere InfosTipp des Monats Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere Infos
|
|
|
Copyright ©2000-2024 vb@rchiv Dieter Otter Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.
Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel
|
|