Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Hilfe! Timer innerhalb eines Thread laufen lassen (https://www.delphipraxis.net/92150-hilfe-timer-innerhalb-eines-thread-laufen-lassen.html)

divBy0 15. Mai 2007 11:41


Hilfe! Timer innerhalb eines Thread laufen lassen
 
Hallo :hi: !

Hab folgendes Problem und komme einfach nicht auf die Lösung.
Also, ich möchte gerne einen eigenen Thread erzeugen, in dem sollte dann ein Timer laufen, welcher dann in entsprechenden Intervallen Daten von einer Schnittstelle liest.

Mein Problem dabei ist, dass ich nicht weiß, wie ich denn den Timer in den Thread bekomme und der Timer dann innerhalb dieses Threads noch eine Funktion oder Prozedur aufruft... :gruebel:

Wenn mir da jemand helfen kann, dann bitte posten...

Danke!!!

Tormentor32 15. Mai 2007 11:43

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Ist ein Thread nicht unter anderem dazu da, damit man keinen Timer braucht?

CCRDude 15. Mai 2007 11:43

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Timer in einem Thread?

Implementiert die Wartezeiten lieber direkter, z.B. mit WaitForMultipleObjects...

SirThornberry 15. Mai 2007 11:46

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
der normale Timer beruht auf WindowMessages. Das heißt das du eine Nachrichtenschleife implementieren müsstest. Aber in einem Thread ist das nicht so sinnvoll. Dann kannst du lieber gleich mit SetTimer arbeiten und eine Call-Backmethode angeben.

divBy0 15. Mai 2007 11:47

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Vielleicht als Erklärung:

Das Programm soll in gleichen Abständen Daten von einer seriellen Schnittstelle abrufen. Da das ganz aber warscheinlich ziemlich langsam wird wollte ich das Abrufen der Daten in einem Thread realisieren, da die anderen Programmteile noch weiterlaufen müssen.

Wie wäre denn ein sauberer Lösungsweg für diese Aufgabe?

SirThornberry 15. Mai 2007 11:51

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
dann könntest du den Timer außerhalb des Threads laufen lassen und im OnTimer den Thread starten! (fände ich die sinnvollste Lösung, dabei natürlich drauf achten das der Timer erst wieder angeworfen wird wenn der Thread fertig ist). Oder du startest bei Programmstart den Thread und legst den Thread für eine bestimmte Zeit schlafen. Aber es macht in deinem Fall recht wenig sinn den Timer die ganze Zeit laufen zu lassen (Timer-Messages empfangen lassen) wenn er nur ab und an gebraucht wird.

Robert Marquardt 15. Mai 2007 11:52

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Na einfach im Thread schlafen mit Sleep.

divBy0 15. Mai 2007 11:57

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Sorry für die warscheinlich dumme Frage:

Ein Thread ist doch keine Endlosschleife, oder? Dann würde der Thread doch nur einmal durchlaufen und dann wird dann beendet.

Werde ich aber gleich mal ausprobieren... Danke SirThornberry und Robert

Robert Marquardt 15. Mai 2007 12:03

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Ein Thread ist eine (Fast)-Endlosschleife. Man hat ueblicherweise eine "while not Terminated do"-Schleife als Kern des Threads. Man sollte deshalb nicht zu lange schlafen, denn man will ja den Thread auch mal beenden.

SirThornberry 15. Mai 2007 12:07

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Genau, ein Thread ist keine Endlosschleife. Letzendlich hast du aber schon immer mit einem Thread gearbeitet (dem Hauptthread der dein Programmfenster malt etc.). Dieser Thread ist auch keine Endlosschleife sondern eine Schleife die solange läuft bis eine bestimmte Message (schließen) empfangen wird. Und genau so verhält es sich bei Threads. Diese laufen genau wie Consolenanwendungen von oben nach unten durch und wenn keine Schleife da ist, läuft das Programm bis zu Ende und schließt sich.

divBy0 15. Mai 2007 12:12

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Ok, danke!

Ich glaube ich habs begriffen... Wenn ich noch was wissen muss, kann ich euch dann auch im Zweifelsfall per PN anschreiben?

SirThornberry 15. Mai 2007 12:18

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
nein! :-D Denn per PN hast nur die etwas davon und andere mit dem gleichen Problem bleiben im Regen stehen. Bei Fragen die im Forum gestellt werden haben alle etwas davon und genau davon lebt ein Forum auch, vom gegenseitigen Helfen

divBy0 15. Mai 2007 12:28

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Ups, so war das auch nicht gemeint...

Den entgültigen Lösungsweg hätte ich dann schon gepostet.

ChrisE 15. Mai 2007 12:32

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Hallo,

wenn der Thread zum Auslesen da sein soll, würde ich folgendes Prinzip verfolgen (als Denkanstoß)
  • Thread liest Daten aus der Schnittstelle in einen "eigenen" Puffer und informiert die Anwendung per Message (selbstdefinieren als Information darüber, dass in dem Puffer neue Daten da sind und an welcher Stelle sie stehen (Puffergröße ausrechnen z.B. auf mind. eine Sekunde Zwischenspeicher)
  • Thread-Klasse selber hat z.B. eine Funktion Abbruch oder Stopp. Intern wird hierbei TEvent verwendet -> Grund siehe unten
  • In der Execute-Methode machst du ein WaitForMultipleObject und "wartest" dort sowohl auf die Schnittstelle (Kann man direkt darauf warten) bzw. auf das TEvent-Object) und entscheidest dann entsprechend Dein verhalten (lesen oder eben abbrechen).
Vorteile:
  • Entkopplung des Lese/ Wartezyklus von der Applikation -> die Applikation kann sich also um "ihre" arbeit kümmern
  • Daten werden (nochmals) gepuffert für die Anwendung und der Thread wird nicht von der "Verarbeitung" der Daten durch die Applikation aufgehalten (Datenverlust)
  • Nicht so Performancelastig, da der Thread wegen WaitForObject nicht so viel Zeit des Prozessors verbraucht wie eine Endlosschleife in einer Applikation
Nachteil:
  • Höhere Aufwand der Programmierung
  • Einarbeiten in das Thema Threads und deren Eigenarten (FreeOnTerminate/Syncronized ...)
  • Erzwungene Trennung und dadurch entstehender Overhead

Viel erfolg dabei :-)

Gruß, Chris

divBy0 15. Mai 2007 13:08

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
So, es hat funktioniert... :thumb:

Hier ist mal der Code:

Delphi-Quellcode:
TMyThread = class(TThread)
  protected
    procedure Execute; override;
    procedure Display;
end;

var
 MyThread : TMyThread;

procedure TMyThread.Display;
begin
  // hier Ausgaben eintragen, Memos, Edits, usw.
end;

procedure TMyThread.Execute;
begin
  while not terminated do
    begin
      // hier Anweisungen (bei mir halt Daten von Steuerung lesen)
      Synchronize(Display);
      sleep(xx); // hier schläft der Thread, bevor er weiterläuft
    end;
end;

procedure TForm2.Button1Click(Sender: TObject);
begin
  MyThread := TMyThread.Create(false);
  MyThread.FreeOnTerminate := true;
end;
Nochmals danke euch allen!!!

@ChrisE:

Auf die Schnittstelle warten funktioniert bei der Anwendung nicht so richtig, daher habe ich den Weg gewählt, dass die Daten entsprechend dem Intervall angefodert und ausgelesen werden. Um den Puffer werde ich mich jetzt kümmern...

Ist auch das erste Mal, dass ich einen Thread benutze, muss mich da jetzt sowieso noch tiefer einarbeiten.

Luckie 15. Mai 2007 13:10

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Warum ist ThreadGo kein Attribut der Thread-Klasse?

divBy0 15. Mai 2007 13:12

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Stimmt eigentlich... werd ich gleich ändern...

Robert Marquardt 15. Mai 2007 13:16

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Statt des ThreadGo nimmt man Terminated. Das ist eine Property des Thread-Objektes.
"while not Terminated do"

divBy0 15. Mai 2007 13:18

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Jetzt hab ich mich so gefreut das es läuft...

also, dann mit WHILE NOT TERMINATED DO

Danke

WS1976 15. Mai 2007 13:23

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Hallo,
ich glaube du schiesst mit Kanonen auf Spatzen.

Der Weg über polling und genau das machst du mit einem zyklisch gestarteten thread ist doch völlig überflüssig.
Wir machen sowas Eventgesteuert über die Routine Ontriggeravailable der Portkomponente.(serielle Schnittstelle Asynch pro)
Das heisst die Routine wird jedesmal (oder auch erst nach bestimmten Vorraussetzungen) durchlaufen, wenn ein Zeichen über die serielle Schnittstelle eintrifft.
Geschickt programmiert ist das viel effektiver als der Weg über threads.

Grüsse

divBy0 15. Mai 2007 13:29

Re: Hilfe! Timer innerhalb eines Thread laufen lassen
 
Das geht leider nicht...
Die Anwendung fragt zyklisch bei der Steuerung die Daten an und diese schickt die dann zurück. Dann werden alle Daten auch gleich in eine Datenbank geschrieben, um sie auch später auswerten oder als Chart anzeigen lassen zu können.

Zuerst hab ich das auch eventgetriggert ausprobiert, hat aber nicht wie gewollt funktioniert. Mit dem Intervall gehe ich dann sicher, dass ich die Daten auch in einem gewissen Zeitfenster bekomme.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:46 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