![]() |
timer in thread?
Hallo,
ich habe ein Threadobjekt TCapture, welches Daten von einer Soundkarte aufnimmt. Das ganze funktioniert über Windows Messages, die der Thread.Execute weiterleitet:
Delphi-Quellcode:
So weit so gut. Jetzt folgende Zusatzaufgabe für den Thread:
procedure TCapture.Execute;
var msg:Tmsg; begin Fwnd:=allocatehwnd(WndProc); //hier ist jetzt dein Windowhandle für MMAudio try if StartCapture then while getMessage(msg,0,0,0) do //warten auf Message DispatchMessage(msg) //verteilen auf das entsprechende Fenster else SetFailed(true); finally logging:=false; LogStop; LogClose; Deallocatehwnd(Fwnd); end; end; Er soll einigermaßen genau t Millisekunden nach dem Aufruf StartCapture einmalig eine Procedure aufrufen. Wie mache ich das am geschicktesten? Bisher habe ich das außerhalb des Threads gemacht, ist aber bei CPU Lastschwankungen zu unzuverlässig, daher muss das in den Hochprioritätsthread mit hinein. Kann ich innerhalb des Threads ein Timerobjekt erzeugen, welches mit derselben Prio läuft wie der Thread? Oder baue ich besser die getMessage-Schleife auf peekMessage um und frage regelmäßig die Tickcounts ab und wenn ja, wie würde das mit peekMessage konkret aussehen? Danke, Thomas |
Re: timer in thread?
Erzeuge einfach einen Timer. Entweder über TTimer oder direkt mit settimer und killtimer an dein Fenster.
|
Re: timer in thread?
Warum nicht einfach
![]() |
Re: timer in thread?
Gut, die/eine NachrichtenSchleife hast du ja schon im Thread, also könnte es was mit dem Timer werden.
Diesen mußt du aber auch in diesem Thread erstellen. Allerdings ... was sind "einige millisekunden"? Timer gehen nicht grade genauch (so grob nur in Intervallen mit Vielfachen von rund 16 Millisenkunden) |
Re: timer in thread?
Die Auflösung von 16ms ist ausreichend. Wenn ichs genauer wollte, könnte ich ja einen MMTimer nehmen.
Sleep geht nicht, weil die Prozessierung der Messages im Thread ja weiterlaufen soll. Noch eine Frage: wenn ich die Zeile
Delphi-Quellcode:
von TCapture.Execute nach TCapture.Create verschiebe, dann meldet FastMM4 beim Stoppen des Threads ein Speicherloch. Warum?
Fwnd:=allocatehwnd(WndProc);
Ich würde den Timer gerne in TCapture.Create erzeugen, aber dazu benötige ich das Fensterhandle Fwnd. |
Re: timer in thread?
Weil du alles im Thread (gerade Fenster und Message-Sachen) machen musst, und der Thread ist nur in Execute (und leider auch in Destroy), aber nicht im Constructor. Auch den Timer zwingend nur in Execute (oder davon aufgerufene Methoden) erstellen und löschen.
|
Re: timer in thread?
ok, verstehe.
|
Re: timer in thread?
.Execute läuft im erstellten Thread und alles, was von da aus aufgerufen wird auch (abgesehn via Synchronize)
.Create läuft noch im erstellenten Thread, da erst danach der eigene Thread erstellt wird. Fenster sind threadgebunden und da die Timer an Fenster gebunden sind, sind diese auch an den erstellenden Thread gebunden. |
Re: timer in thread?
Wie erstelle ich denn konkret den Timer in meinem Thread?
Delphi-Quellcode:
geht nicht, weil TCapture (=self) und TObject nicht kompatibel sind. Ich habe ja ein virtuelles Fenster in meinem Thread. Wie komme ich da ran, d.h. was muss ich statt Self benutzen?
with TTimer.Create(Self) do
begin Interval := 1000; Enabled := False; OnTimer := MyTimerEventHandler; end; |
Re: timer in thread?
statt self einfach nil nehmen TTimer erstellt sich intern immer eh ein eigenes Fenster, über welches es läuft ... "self" wäre nur der Owner und dieser kümmert sich nur um das automatische Löschen Timers.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 13: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