AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Wie eine Uhr über einen Thread aktualisieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wie eine Uhr über einen Thread aktualisieren

Ein Thema von willyxv · begonnen am 5. Nov 2010 · letzter Beitrag vom 6. Nov 2010
Antwort Antwort
Seite 1 von 2  1 2      
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#1

Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 12:13
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:
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;
Bin für jede Hilfe Dankbar

MfG Willy
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#2

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 12:18
einfach einen TThread erstellen, der diese Abfrage erledigt?

Das Label gibst du dann einfach über eine seperate methode im Thread aus mit Synchronize.
Steven
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 12:19
ich habe das ganze schon über einen Thread versucht aber ich weiß nicht wie ich das Label aktualisiert bekomme.
Das Stichwort heißt Delphi-Referenz durchsuchenSynchronize.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#4

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 12:23
Tutorial: Hier
Steven
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#5

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 15:16
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
Speicher := TCPClient.IOHandler.ReadLn(wert4); // Datenempfang .
Also muss man hier ansetzen und vom blockierenden Zugriff auf ein eventgesteuertes Vorgehen umstellen.
Andreas
  Mit Zitat antworten Zitat
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#6

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 17:03
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
  Mit Zitat antworten Zitat
youuu

Registriert seit: 2. Sep 2008
Ort: Kleve
822 Beiträge
 
Delphi 2010 Professional
 
#7

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 17:06
Das seh ich etwas anderst, klar ist
Zitat:
man darf Controls aus der VCL nur aus dem Hauptthread ansprechen, da die VCL nicht "threadfest" ist.
Allerdings wieso die Komponente nicht im Thread erstellen? die Label Übergabe mit Synchronize dauert eine Milisekunde und die DB Abfrage läuft schön gemütlich im Thread und nichts wird blockiert.
Steven
  Mit Zitat antworten Zitat
willyxv

Registriert seit: 25. Okt 2010
29 Beiträge
 
Delphi XE Enterprise
 
#8

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 17:24
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.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#9

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 5. Nov 2010, 17:24
...die Label Übergabe mit Synchronize dauert eine Milisekunde und die DB Abfrage läuft schön gemütlich im Thread und nichts wird blockiert.
Wenn ein Thread die Synchronize-Methode aufruft, dann heisst das noch lange nicht, dass die übergebene Methode sofort ausgeführt wird.
Beispiel:
Delphi-Quellcode:
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;
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.
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.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#10

AW: Wie eine Uhr über einen Thread aktualisieren

  Alt 6. Nov 2010, 04:42
Ich war eigentlich der Meinung, dass Synchronize anders funktioniert.

Denn der Thread läuft erst dann weiter, wenn die Procedere im Synchronize abgearbeitet wurde.
Delphi-Quellcode:
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;
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.
Aber es werden nicht unzählig viele Nachrichten geschickt, sondern nur eine und die wartet auf eine Reaktion aus dem Hauptthread.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:26 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz