Zitat von
clownxx:
Wenn ich das ganze mit deiner vorgeschlagenen Klasse versuche, wird die Procedure DoEvents auch nie abgearbeitet, geanu wie wenn ich synchronize verwende.
DoEvents kannst du doch dann direkt aufrufen. Somit kann ich nun erstmal schlecht nachvollziehen, warum du niemals zum DoEvents kommst.
Zitat von
clownxx:
Lass ich die ganzen Synchronisationsmechanismen weg klappt das ja. Wenn ich nun in der Callback ein Showmessage(text) aufrufe, ist der Button des Fensters ganz klein und es steht erstmal nichts drin.
Weil du dann immernoch im Thread hängst und nicht im
VCL Thread. Dass müsstest du in den
VCL Thread synchronisieren. Dadurch auch der Fehler, da die Elemente vom falschen (der
VCL unbekannten) Thread aus aufgerufen werden. Die
VCL ist grundsätzlich nicht thread-safe!
Zitat von
clownxx:
Schreibe ich den TExt den ich in der Callback empfange einfach in ein Memo ist alles top. Dann wird dieser korrekt angezeigt.
Es tritt nur kein offensichtlicher Fehler auf, heißt aber nicht, dass alles klappt.
Zitat von
clownxx:
Ist das normal oder was habe ich hier noch falsch gemacht?
Ok, eine Idee, wie ich das ganze anfassen würde.
Anforderungen:
1. Du hast einen Thread der ab und zu Daten ermittelt, welche in einen Datenspeicher abgelegt werden.
2. Wenn was empfangen wurde, dann müssen die Daten an die Applikation weitergereicht werden.
3. Zu diesem Zeitpunkt muss dieses Ereignis der Applikation mitgeteilt werden
Schnittstelle ist der Datenspeicher. Dieser muss synchronisiert werden, damit nicht gleichzeitig gelesen und geschrieben wird.
Lösung:
Dazu wird eine Instanz von
TMultiReadExclusiveWriteSynchronizer erzeugt, welche dem Thread und einer
DLL Funktion bekannt gemacht wird.
Der Thread läuft und immer wenn er Daten hat, dann nutzt er BeginWrite/EndWrite um in den Datenspeicher die neuen Daten abzulegen.
Die o.g.
DLL Funktion dient der Applikation um die Daten abzuholen. Dazu ruft die Applikation die Funktion auf und darin (
DLL Seite) wird die
TMultiReadExclusiveWriteSynchronizer Instanz mit BeginRead/EndRead verwendet.
Soweit haben wir die Datenübergabe samt thread-Sicherheit geschaffen. Nun fehlt nur noch, dass die Applikation Bescheid bekommt, wenn neue Daten angekommen sind. Dazu kann die Applikation einmalig eine
DLL Funktion aufrufen, bei der sie ein Fensterhandle mitgibt. Dieses merkt sich die
DLL und sendet u.a. mit PostMessage innerhalb des Threads eine Botschaft ab. Innerhalb von BeginWrite/EndWrite im Thread darf die Liste auch gelesen werden (Write ist Exklusiv) und dadurch könnte die abgesendete Message sogar die Anzahl der empfangenen Daten und noch vorhandenen Daten in dem Datenpuffer übermittelt werden. Damit weiss die Applikation auch gleich, wie oft sie die o.g. Funktion zum Daten abholen aufrufen kann/muss.
Damit wird das Auslesen innerhalb des
VCL Threads angestossen (durch die Botschaft) und ist somit mit der
GUI synchron.
Hinweis:
Die von der Applikation ausgelesenen/abgefragten Daten sollen bestimmt danach im Datenpuffer entfernt werden. Wenn die Applikation mehrfach liest bis sie alle Daten hat, dann wäre es besser, wenn es eine Löschen Funktion gibt. Dafür wäre nämlich ein exklusives BeginWrite/EndWrite nötig, und das würde für jeden einzelnen Datenblock den ganzen Thread so stark behindern, dass der Thread nichts mehr bringt. Von daher lieber so auslesen und extra löschen.