Avatar billede zerohero Nybegynder
02. april 2002 - 10:22 Der er 19 kommentarer og
1 løsning

Ttimer

Jeg har erfaret at Ttimer opføre sig forskelligt afhængig af hvilken Windows platform man anvender. Jeg har lavet en lille forsøgs program der viser den tydelige forskel...

Ttimerens interval er sat til 10 Dvs. at i bliver forøget med 1 integer med interval 10. Her er resultat:

Windows 2000 (WinNT)

i: 100 - seconds: 1
i: 200 - seconds: 3
i: 300 - seconds: 4
i: 400 - seconds: 6
i: 500 - seconds: 7
i: 600 - seconds: 9
i: 700 - seconds: 10
i: 800 - seconds: 12
i: 900 - seconds: 14
i: 1000 - seconds: 15
i: 1100 - seconds: 17
i: 1200 - seconds: 18
i: 1300 - seconds: 20
i: 1400 - seconds: 21
i: 1500 - seconds: 23

Windows 98 (Win32)

i: 100 - seconds: 6
i: 200 - seconds: 11
i: 300 - seconds: 17
i: 400 - seconds: 22
i: 500 - seconds: 28
i: 600 - seconds: 33
i: 700 - seconds: 39
i: 800 - seconds: 44
i: 900 - seconds: 50
i: 1000 - seconds: 55
i: 1100 - seconds: 61
i: 1200 - seconds: 66
i: 1300 - seconds: 72
i: 1400 - seconds: 77
i: 1500 - seconds: 83

som I kan se er der en tydelig forskel. I Windows 98 køre Ttimer meget langsommere end på Windows 2000! Når i er lig med 400, i Windows 2000, er der gået 6 sekunder. Den samme tid som det Ttimer at runde 100 i Windows 98. Hmmm... hvorfor? og hvordan kan jeg gøre Ttimer "stabil"?

ZeroHero
Avatar billede borrisholt Novice
02. april 2002 - 10:25 #1
TTimer baserer sig på et win32 API kald ... Brug en tråd baseret timer den er bedere :

(*********************************************
TThreadTimer -> TComponent

A timer replacement that uses a thread to manage
the timer events.
*********************************************)
unit ThreadTimer;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, MMSystem;

type

  TThreadTimer = class;

  TTimerThread = class( TThread )
  private
    tt: TThreadTimer;
  protected
    procedure DoExecute;
  public
    constructor CreateTimerThread( tt: TThreadTimer );
    procedure Execute; override;
  end;

  TThreadTimer = class(TComponent)
  private
    FInterval: integer;
    FPriority: TThreadPriority;
    FOnTimer: TNotifyEvent;
    bStop: boolean;
    bRunning: boolean;
    FEnabled: boolean;
  protected
    procedure setEnabled( b: boolean );
    procedure Start;
    procedure Stop;
  public
    constructor Create( AOwner: TComponent ); override;
  published
    property Enabled: boolean read FEnabled write setEnabled;
    property Interval: integer read FInterval write FInterval;
    property ThreadPriority: TThreadPriority read FPriority write FPriority default tpNormal;
    property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
  end;

procedure Register;

implementation

(*********************************************
Initialize thread priority
*********************************************)
constructor TThreadTimer.Create( AOwner: TComponent );
begin
  inherited Create( AOwner );
  FPriority := tpNormal;
end;

(*********************************************
Changing the Enabled property calls either
Start or Stop protected methods.
*********************************************)
procedure TThreadTimer.setEnabled( b: boolean );
begin
  if b then
    Start
  else
    Stop;
  FEnabled := bRunning;
end;

(*********************************************
Starting the timer creates an instance of
TTimerThread and launches the thread.
*********************************************)
procedure TThreadTimer.Start;
begin
  if bRunning then
    Exit;
  bStop := false;
  if not (csDesigning in ComponentState) then
  begin
    with TTimerThread.CreateTimerThread( self ) do
    begin
      Priority := FPriority;
      Resume;
    end;
  end;
  bRunning := true;
end;

(*********************************************
Stopping the timer just sets the stop flag to
true, the TTimerThread's Execute method will
then end and the thread will be destroyed.
*********************************************)
procedure TThreadTimer.Stop;
begin
  bStop := true;
  bRunning := false;
end;

(*********************************************

*********************************************)
constructor TTimerThread.CreateTimerThread( tt: TThreadTimer );
begin
  inherited Create( true );
  self.tt := tt;
  FreeOnTerminate := true;
end;

(*********************************************
Execute method for the spawned thread.  Just
repeats while the timer is enabled, and calls the
timer object's OnTimer event.
*********************************************)
procedure TTimerThread.Execute;
var
  SleepTime, Last: integer;
begin
  while not tt.bStop do
  begin
    Last := timeGetTime;
    Synchronize( DoExecute );
    SleepTime := tt.FInterval - ( timeGetTime - Last );
    if SleepTime < 10 then
      SleepTime := 10;
    sleep( SleepTime );
  end;
end;

(*********************************************
This method is called within the TTimerThread's
Execute, using the Synchronize method.  This is
because we need to call the event handler from
the main VCL thread.
*********************************************)
procedure TTimerThread.DoExecute;
begin
  with tt do
  begin
    if Assigned( FOnTimer ) then
      FOnTimer( tt );
  end;
end;

procedure Register;
begin
  RegisterComponents( 'Borrisholt', [TThreadTimer] );
end;

end.


Jens B
Avatar billede zerohero Nybegynder
02. april 2002 - 10:50 #2
Hej BorrisHolt...

Ja, jeg har lige lavet en lign. forsøg med din komponent:

Windows 2000 (WinNT)

i: 100 - seconds: 2
i: 200 - seconds: 3
i: 300 - seconds: 5
i: 400 - seconds: 6
i: 500 - seconds: 8
i: 600 - seconds: 9
i: 700 - seconds: 11
i: 800 - seconds: 12
i: 900 - seconds: 14
i: 1000 - seconds: 16
i: 1100 - seconds: 17
i: 1200 - seconds: 19
i: 1300 - seconds: 20
i: 1400 - seconds: 22
i: 1500 - seconds: 23

Windows 98 (Win 32)

i: 100 - seconds: 1
i: 200 - seconds: 3
i: 300 - seconds: 4
i: 400 - seconds: 6
i: 500 - seconds: 7
i: 600 - seconds: 8
i: 700 - seconds: 10
i: 800 - seconds: 11
i: 900 - seconds: 13
i: 1000 - seconds: 14
i: 1100 - seconds: 15
i: 1200 - seconds: 17
i: 1300 - seconds: 18
i: 1400 - seconds: 20
i: 1500 - seconds: 21

Det har hjulpet meget... men helt nøjagtigt er det ikke. Windows 98 er ca. 1-2 sekunder langsommere... meeen mon ikke det går an... :-))

ZeroHero
Avatar billede zerohero Nybegynder
02. april 2002 - 10:57 #3
Takker for dit hurtige svar :-))
Avatar billede borrisholt Novice
02. april 2002 - 10:59 #4
Det kan du nok ikke komme nærmer .. WIn98 stinker !


Jens B
Avatar billede zerohero Nybegynder
02. april 2002 - 11:16 #5
Der er lige et andet lille (mærkligt) problem... Når jeg afspiller en CD, hvilket jo ikke burde tage ret mange af computerens resourcer, så er hverken TThreadTimer eller TTimer stabile under Windows 98 men i Windows 2000 køre det ok... Jeg ved ikke præcis, hvor skoen trykker, om det er mit OpenGL grafik eller Win32 API kald der er årsagen... måske du kunne hjælpe med det?
Avatar billede borrisholt Novice
02. april 2002 - 11:18 #6
nej det kan jeg ikke ... Problemet er (så vidt jeg ved) win98's kærne

Jens B
Avatar billede zerohero Nybegynder
02. april 2002 - 11:20 #7
Med andre ord... hvis du med sikkerhed ved at det ikke er Win32 API Kald der kan være årsagen, så må det jo mit OpenGL - jeg har nemlig hørt en lille fugl synge om at du ikke er den store 3D HAJJJJ *G*
Avatar billede zerohero Nybegynder
02. april 2002 - 11:21 #8
ØV... det var da en skam...
Avatar billede zerohero Nybegynder
02. april 2002 - 11:29 #9
Jeg tænkte på om du eventuelt var interesseret i at se mit lille 3D projekt? - som din TThreadTimer har været skyld i at den nu køre stabilt både under WinNT og Win32...
Avatar billede borrisholt Novice
02. april 2002 - 11:31 #10
jo jo ... Send bare exe filen .. Jeg får ikke kigget på koden :-)

Jens B
Avatar billede zerohero Nybegynder
02. april 2002 - 11:33 #11
ok... men kan du ikke lige give mig din mail..
Avatar billede zerohero Nybegynder
02. april 2002 - 11:35 #12
nå... ja kan godt huske den nu...
Avatar billede zerohero Nybegynder
02. april 2002 - 11:38 #13
så er den sendt... God Fonøjelse...
Avatar billede borrisholt Novice
02. april 2002 - 11:41 #14
tak ... Den er sq fed !

Jens B
Avatar billede borrisholt Novice
02. april 2002 - 11:41 #15
Hvid du vil afspille en CD samtidig med .. Så skal du blot skrive en ny CD-afspiller .. som er trådbaseret helt ned i mindste detaljer ....

Jens B
Avatar billede borrisholt Novice
02. april 2002 - 11:48 #16
Du har ret  : Jeg er ikke den helt store 3D haj .. men jeg klarer mig da meget godt på andre områder ...

Jens B
Avatar billede zerohero Nybegynder
02. april 2002 - 16:52 #17
Det lige hvad du gør :-)) Kan du ikke lige fortælle mig lidt mere om det der trådbaseret - jeg er nemlig ikke helt klar over hvad der menes!!!
Avatar billede borrisholt Novice
02. april 2002 - 17:00 #18
jammen det er ikke så svært ...

Du skal lave en klasse der kan afspille CDA .. Den klasse skal være en tråd .. Eller i hverfald eje en tråd der læser fra din CD

Jens b
Avatar billede zerohero Nybegynder
02. april 2002 - 17:27 #19
jamen hvad betyder en "tråd" - i programmerings verden?
Avatar billede borrisholt Novice
03. april 2002 - 08:32 #20
en Tråd ? Det er en klasse der arver fra TThread !

Jens B
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester