Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   GetTickCount vs. TTimer (https://www.clubdelphi.com/foros/showthread.php?t=33788)

Wonni 17-07-2006 13:41:17

GetTickCount vs. TTimer
 
Hola :)

Tengo el libro de los tomos de Delphi: "Nucleo del Api Win32" y en el capitulo 15 ( Funciones de temporización ) trae un ejemplo de como emular un temporizador. El ejemplo muestra un label parpadeando. El caso es que yo pense que tratando con el Api ( tal y como dice el libro ) se consigue una mejor ejecucion del programa, consumir menos recursos. Pues resulta que construyo el programita con dos opciones:

1ª - Mostrar el label parpadeando con un TTimer y
2ª - Mostrar el label parpadeando con el codigo que trae el libro utilizando GetTickCount.

Cuando ejecuto el programa con el TTimer, voy al monitor del sistema y el uso de CPU no sube nunca del 1 %

Cuando ejecuto el programa con GetTickCount, el uso de CPU no se mueve del 100 % !!!! :eek:

¿como es posible? se supone que deberia ser mas liviano.

Este es el codigo completo:

Código Delphi [-]
unit Principal;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;
type
  TFormPrincipal = class(TForm)
    BotonIniciarConGet: TButton;
    LabelDelphi: TLabel;
    BotonDetenerGet: TButton;
    BotonIniciarConTTimer: TButton;
    BotonDetenerTTimer: TButton;
    TimerParpadeo: TTimer;
    procedure BotonIniciarConGetClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BotonDetenerGetClick(Sender: TObject);
    procedure BotonIniciarConTTimerClick(Sender: TObject);
    procedure BotonDetenerTTimerClick(Sender: TObject);
    procedure TimerParpadeoTimer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  FormPrincipal: TFormPrincipal;
  Running: Boolean;     // variable de control del bucle

implementation
{$R *.dfm}
Procedure Timerando;
Begin
End;
Procedure FlashLoop;
Var
 StartTick: DWORD;   // Hora de inicio
Begin
 //Obtener la hora actual
 StartTick := GetTickCount;
 //Si el bucle continua...
 While Running Do
  Begin
   //...si ha trasncurrido un segundo
   If (GetTickCount - StartTick) > 1000 Then
    Begin
     //...actualizar etiqueta
     FormPrincipal.LabelDelphi.Visible := not FormPrincipal.LabelDelphi.Visible;
     //Reinicializar hora de inicio para siguiente iteracion
     StartTick := GetTickCount;
    End;
   // Necesario para que el bucle no "bloquee" la maquina
   Application.ProcessMessages; 
  End;
End;
procedure TFormPrincipal.BotonIniciarConGetClick(Sender: TObject);
begin
 //Inicializar variable de control...
 Running := TRUE;
 //... y lanzar el bucle
 FlashLoop;
end;
procedure TFormPrincipal.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 Running := FALSE;
 TimerParpadeo.Enabled := FALSE;
end;
procedure TFormPrincipal.BotonDetenerGetClick(Sender: TObject);
begin
 Running := FALSE;
end;
procedure TFormPrincipal.BotonIniciarConTTimerClick(Sender: TObject);
begin
 TimerParpadeo.Enabled := TRUE;
end;
procedure TFormPrincipal.BotonDetenerTTimerClick(Sender: TObject);
begin
 TimerParpadeo.Enabled := FALSE;
end;
procedure TFormPrincipal.TimerParpadeoTimer(Sender: TObject);
begin
 FormPrincipal.LabelDelphi.Visible := not FormPrincipal.LabelDelphi.Visible;
end;
end.

Saludos !!

seoane 17-07-2006 13:54:37

El problema no es con la función GetTickCount, que tiene sus manías pero esta no es una de ellas. Lo que pasa es que la utilizas dentro de un bucle, si no haces algún tipo de espera dentro del bucle este termina usando la CPU al 100%. Una solución sencilla es hacer una pequeña espera dentro del bucle.

Código Delphi [-]
 StartTick := GetTickCount;
 //Si el bucle continua...
 While Running Do
  Begin
   //...si ha trasncurrido un segundo
   If (GetTickCount - StartTick) > 1000 Then
    Begin
     //...actualizar etiqueta
     FormPrincipal.LabelDelphi.Visible := not FormPrincipal.LabelDelphi.Visible;
     //Reinicializar hora de inicio para siguiente iteracion
     StartTick := GetTickCount;
    End;
   // Necesario para que el bucle no "bloquee" la maquina
   Application.ProcessMessages; 
   Sleep(100); // Aqui le damos tiempo a la CPU para respirar
  End;

Wonni 17-07-2006 14:03:21

Gracias seoane, funciona muy bien :)

Ahora en el monitor de sistema consume exactamente igual GetTickCount que TTimer. No se mueve del 1% ( a veces 0 en ambos metodos ).

Entonces, supongo que da igual uno q otro. ¿no?

Saludos !!

seoane 17-07-2006 14:16:33

Cita:

Empezado por Wonni
Entonces, supongo que da igual uno q otro. ¿no?

Yo creo que se utilizan para hacer cosas diferentes. Mientras que GetTickcount es muy útil para controlar el tiempo dentro dentro de una función, por ejemplo para implementar un Timeout, si lo que queremos es ejecutar un evento a intervalos regulares es mucho mejor usar un TTimer, que a fin de cuentas solo encapsula las APIs SetTimer y KillTimer.

Wonni 17-07-2006 14:32:57

ok, ya me ha quedado claro.

Gracias otra vez seoane :)

Saludos !!


La franja horaria es GMT +2. Ahora son las 17:24:44.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi