![]() |
Wie eine Uhr über einen Thread aktualisieren
Hallo,
in meinem Program wird über einen Timer alle 5 Sekunden über das netzwerk ein Pumpenturm abgerufen. Die Empfangenen Daten werden dann verglichen, in eine sql Datenbank geschrieben und auf verschiedenen Labels und Memos angezeigt. Nun zu meinem Problem. Es soll eine Uhrangezeigt werden welche die aktuelle Uhrzeit anzeigt. Ich habe versucht dies über einen timer zu verwirklichen, jedoch belibt dieser immer kurz stehen wenn die Netzwerkanfrage raus geht und dies dauert 3 Sekunden. Also springt meine Uhr immer um 3 Sekunden weiter und läuft dann 2 Sekunden wieder und springt wieder weiter. Wie schaffe ich es die Uhr unabhänig von der Datenbankabfrage zum laufen zu brinen? ich habe das ganze schon über einen Thread versucht aber ich weiß nicht wie ich das Label aktualisiert bekomme. Die Datenbankanfrage kann ich auch nicht auslagern da ich viele Daten direkt per Memo anzeigen lasse. Hier das Programm wie es bisher läuft:
Delphi-Quellcode:
Bin für jede Hilfe Dankbar
procedure TForm1.LeseTimerTimer(Sender: TObject);
var g : integer; begin TCPClient.IOHandler.Write(); // Start des Abfragebefehls for g := 0 to Pumpenanzahl - 1 do BEGin Speicher := TCPClient.IOHandler.ReadLn(wert4); // Datenempfang // Vergeliche und Ausgaben. TCPClient.IOHandler.Write(); // Bestätigung des Empfangs und anforderung der nächseten Pumpe END; // die Schleife braucht etwa 3 Sekunden und in dieser Zeit steht die Uhr. end; procedure TForm1.ZeitTimerTimer(Sender: TObject); begin Zeit.Caption := datetostr(now) + ' ' + timetostr(now); end; MfG Willy |
AW: Wie eine Uhr über einen Thread aktualisieren
einfach einen TThread erstellen, der diese Abfrage erledigt?
Das Label gibst du dann einfach über eine seperate methode im Thread aus mit Synchronize. |
AW: Wie eine Uhr über einen Thread aktualisieren
Zitat:
![]() |
AW: Wie eine Uhr über einen Thread aktualisieren
Tutorial:
![]() |
AW: Wie eine Uhr über einen Thread aktualisieren
Wenn der Hauptthread blockiert, weil er in irgendeiner Funktion für eine gewisse Zeit gefangen ist,
dann hilft auch kein 2. Thread für die Uhr. Grund: man darf Controls aus der VCL nur aus dem Hauptthread ansprechen, da die VCL nicht "threadfest" ist. Synchronize macht ja nichts anderes, als dem Hauptthread eine Message zu schicken mit der Anweisung "lieber Hauptthread bitte führe für mich die übergebene Methode aus". Also ist das Grundproblem, dass der Hauptthread zu lange blockiert. Es tut das wahrscheinlich in der Zeile
Delphi-Quellcode:
.
Speicher := TCPClient.IOHandler.ReadLn(wert4); // Datenempfang
Also muss man hier ansetzen und vom blockierenden Zugriff auf ein eventgesteuertes Vorgehen umstellen. |
AW: Wie eine Uhr über einen Thread aktualisieren
Danke shmia,
stimmt an der Stelle wartet er auf die Antwort und blockiert. ich werd also versuchen die Datenbankanfrage irgendwie anderst hin zu bekommen und versuchen sie in einen Thread auszulagern. MfG Willy |
AW: Wie eine Uhr über einen Thread aktualisieren
Das seh ich etwas anderst, klar ist
Zitat:
|
AW: Wie eine Uhr über einen Thread aktualisieren
dacht ich zunächst auch, aber bei readln(endsignal) wartet er bis er daten mit dem entsprechendem endsignal in der Klammer empfangen hat und in dieser zeit macht er überhaupt nix. Daher werd ich wohl diese Abfrage in einen Extra Thread packen müssen damit der Hauptthread weiterlaufen kann.
|
AW: Wie eine Uhr über einen Thread aktualisieren
Zitat:
Beispiel:
Delphi-Quellcode:
Würde der Hauptthread durch eine längere Berechnung sagen mir mal 15 Sekunden blockiert werden, dann würde der UhrenThread munter weiterlaufen und über Synchronize 15 Messages an den Hauptthread schicken.
procedure TUhrenThread.UhrzeitLabelAnzeigen;
begin // wird im Kontext des Hauptthreads ausgeführt Form1.UhrzeitLabel.Text := TimeToStr(Now); end; procedure TUhrenThread.Execute; begin while not Terminated do begin Sleep(1000); // Synchronize schickt nur eine Message an den Hauptthread Synchronize(UhrzeitLabelAnzeigen); end; end; Der Hauptthread kann die Messages aber erst wieder verarbeiten, nach dem er 15 Sek blockiert war. Jetzt "sieht" der Hauptthread 15 Messages und führt 15 Mal TUhrenThread.UhrzeitLabelAnzeigen aus. (für eine flüssige Uhrzeitanzeige ist es viel zu spät) ==> wenn der Hauptthread blockiert, dann friert auch das User Inferface / die Anzeige ein. Also: der Hauptthread darf/sollte nie längere Zeit blockieren. Man könnte z.B. die Kommunikation über TCP/IP und den Zugriff auf die Datenbank in einen Thread packen. Dann wäre der Hauptthread ohne Blockade und eine Anzeige einer Uhrzeit wäre kein Problem. |
AW: Wie eine Uhr über einen Thread aktualisieren
Ich war eigentlich der Meinung, dass
Delphi-Quellcode:
anders funktioniert.
Synchronize
Denn der Thread läuft erst dann weiter, wenn die Procedere im Synchronize abgearbeitet wurde.
Delphi-Quellcode:
Mit diesem Code bleibt nicht nur die Fensteranzeige stehen, sondern auch der Thread bleibt hängen, da keine Synchronisierung erfolgen kann, weil die Nachrichten vom Hauptthread nicht verarbeitet werden.
procedure FooThread.SyncProc;
begin Sleep( 5000 ); end; procedure TFooThread.Execute; begin while not Terminated do begin Synchronize( SyncProc ); end; end; procedure TFooMainForm.StartThread; begin with TFooThread.Create do try while not Terminated do Sleep( 500 ); finally Free; end; end; Aber es werden nicht unzählig viele Nachrichten geschickt, sondern nur eine und die wartet auf eine Reaktion aus dem Hauptthread. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz