Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Un TIMER miente!!!???! (https://www.clubdelphi.com/foros/showthread.php?t=26360)

marceloalegre 20-10-2005 15:09:35

Un TIMER miente!!!???!
 
Buen Dia:
Les molesto para consultarles si alguien ha tenido la experiencia de notar que el componente timer del delphi "miente" por asi decirlo,,, o en realidad no trabaja correctamente segun observe.
Lo que hago es desde una aplicacion envio por socket a 3 pc un tiempo x y le digo que "empiese a contar" al cronometrar eso con un reloj, note variaciones de aproximadamente 10 segundos en 5 minutos!! en todas las maquinas distinto...

por las dudas: como cuento el tiempo?! asi:

para adelante:
Código:

formx.LabelTimer.Caption:= FormatdateTime('hh:mm:ss',StrToDateTime (formx.LabelTimer.Caption)+0.00002);
para atras:
Código:

formx.LabelTimer.Caption:= FormatdateTime('hh:mm:ss',StrToDateTime (formx.LabelTimer.Caption)-0.00001);
a ver si eso les parece correcto...????

al parecer voy a tener que usar algo mas preciso que un timer o cambiar el algoritmo... alguien tiene conocimiento de este tema? Muchas gracias!

dec 20-10-2005 15:41:56

Hola,

Ignoro si el componente "TTimer" puede fallar tantos segundos en tan poco tiempo, pero, lo que no ignoro es que hay componentes que implementan un "TTimer" más fiable, o más preciso, una especie de "THighTimer". ¿Dónde encontrar alguno de estos componentes? Pues, por ejemplo, en Torry's Delphi Pages toparás con algunos de ellos.

Lepe 20-10-2005 16:51:38

Un Timer de delphi no tiene fallos.

La verdad es que no veo la forma de contar, ya que ahí pillas un label, lo conviertes a datetime, despues le sumas una fracción, y por último le cambias el formato. ¿Donde está el timer? no lo veo por ningún sitio. Desde luego no es forma fiable de contar el tiempo, y mucho menos echarle la culpa al pobre Timer :D.

No sé como estas haciendo las cosas, pero yo usaría un timer simplemente poniendole el tiempo total que ha de esperar.

De todas formas, si necesitas más precisión, mira la ayuda de GetTickCount de la unidad Windows.

saludos

dec 20-10-2005 18:09:54

Hola,


Cita:

Empezado por Lepe
Un Timer de delphi no tiene fallos.

Bueno. Conste que yo no he querido decir eso, sino constatar el hecho de que existen "Timer's" con mayor resolución, por decirlo de algún modo. Me parece raro que sean cinco segundos de "desfase" los que se alcanzen, pero, he probado alguna vez alguno de los "Timer's más precisos" y, en los ejemplos que acompañan a dichos componentes suele haber una muestra, precisamente, de cómo estos son más precisos que los "TTimer" de Delphi. Lamento no recordar exactamente el componente en cuestión, pero, en el enlace de más arriba pueden encontrarse varios de ellos: probablemente incluyan ejemplos en que se muestre la diferencia entre ambos "TTimer"y "THighTimer", por llamar de algún modo al "TTimer especial". :p

dec 20-10-2005 18:12:04

Hola de nuevo,

Acaso quepa añadir que, efectivamente, los "THighTimer's" son usados, me parece a mí, no en intervalos demasiado "largos"; es precisamente ahí donde muestran su mayor eficacia respecto a los "TTimer" que acompañan a Delphi. Quiere decirse que este puede medir un tiempo de "0.500" milisegundos, y acaso los otros rezen "0.230" segundos, o resultados por el estilo. ;)

marceloalegre 20-10-2005 20:16:04

Mi estimado lepe... se supone que como estoy hablando del timer, si hay un timer :), lo que mostre de codigo es lo que esta adentro del timer.... :) ... no entiendo por que preguntas esooo....??
Si, quizas es porque dije que lo mando por socket... se puede interpretar otra cosa... o sea yo por socket mando la orden de que se active el timer con el codigo que he dejado expresado anteriormente, si se malentendio, mil disculpas!

En cuanto a lo que tu dices que el timer no tiene fallos... No me cierra bajo ningun concepto!!!
Imagina... tu pones un timer a hacer "algo" a 1000 ms...
perfecto....
emmm imagina que los recursos del cpu estan al 80 % o sea la pc esta a full....

entonces... no imaginas que el timer se ir un poco de tiempo imaginemos...
1010 ms.... o sea.,, si muestro algo en pantalla considero que siempre poco a poco se va a ir adelantando...

Lo digo comprobado empiricamente.. :) agarramos las pc y pusimos a tirar datos por pantalla con algunos for's paralelos para sacar recursos al procesador... y el adelanto fue detectado perfectamente... asi que si... el timer no es perfecto...
Ahora si , con GetTickCount haciendo lo debido, podria solucionar el problema....


Saludos!.

Casimiro Noteví 20-10-2005 20:27:34

Por mi experiencia, y por lo que he leído :D, sé que el timer de delphi no es muy exacto. Si requieres más precisión o necesitas de varios timer te aconsejo el que trae las RX, que tiene la particularidad de ser un TrxTimerList, así con un único "componente" en tu programa puedes gestionar multitud de timers.

Lepe 21-10-2005 12:22:55

Cita:

Empezado por kanvictor
Mi estimado lepe... se supone que como estoy hablando del timer, si hay un timer :), lo que mostre de codigo es lo que esta adentro del timer.... :) ... no entiendo por que preguntas esooo....??

No dijiste que ese código está dentro del evento OnTimer.

Creía que estabas midiendo el tiempo con esa expresión, y desde luego, realizar conversiones de texto a número y sumarle fracciones de tiempo no es la forma de medir el tiempo. La forma correcta sería con GetTickCount, si quieres toda la precisión.

Dices que el resultado de esa expresión es la que se usa para enviarla por sockets. Creía que esa expresión era la que realmente medía el tiempo !!

Yo he realizado pruebas de ese estilo con timers, y no he tenido retardo, en realidad los retardos se producían en mi código, y creo que tambien es tu caso (intuyo).

Dentro del timer, ejecutas ese código (ya consume algo de tiempo, mínimo, porque son 3 o 4 conversiones), despues lo envias por sockets, (tambien se consume un tiempo más considerable), el programa Cliente Recibe el tiempo que ha de activar su timer y lo pone en marcha, Justo en este punto es cuando debes empezar a contar el tiempo.

Si usas un reloj de pulsera, tambien hay retardos en pulsar el botón o parar el crono, por tanto no es fiable.

No es lógico medir el tiempo desde antes de lanzarlo por sockets.

Quizás lo esté entendiendo de otra forma :rolleyes:.

En cuanto a que el sistema esté al 80 % y se pase por alto, o se retrase..., solo puedes darle prioridad a tu proceso en windows, para que windows lo trate con más "atención" que al resto. Pero en este caso, no se trata de retardos del timer, sino retardos de Windows en procesar el mensaje desde el cronómetro interno del sistema (hardware) hasta que llega a tu aplicación.

Lo ideal, como estas viendo es unir la prioridad de proceso con GetTickCount.

Espero que ahora me haya expresado mejor.

saludos

Lepe 21-10-2005 12:27:09

Cita:

Empezado por Casimiro Notevi
Por mi experiencia, y por lo que he leído :D, sé que el timer de delphi no es muy exacto. Si requieres más precisión o necesitas de varios timer te aconsejo el que trae las RX, que tiene la particularidad de ser un TrxTimerList, así con un único "componente" en tu programa puedes gestionar multitud de timers.

El Timer tiene como límite, los milisegundos, si quieres diezmilesimas, entonces si necesitas mayor precisión y tienes que usar otra técnica.

Este es el punto que quería aclarar.

saludos

Lepe 22-10-2005 12:06:00

Me quedé pensando y al final, ni siquiera GetTickcount es fiable.

Mira este truco de Ian Marteens.

Crandel 31-10-2005 23:29:51

Recien leo este hilo, asi que voy a intentar aclarar algunas cosas.

Primero, kanvictor estas mesclando dos cosas, una es contar el tiempo transcurrido entre dos eventos y el otro es mostrar este tiempo. Lo escencial es separarlos.

Donde esta tu problema? radica en que cuando le decis TTimer, que cada un segundo (por ejemplo) te genere el evento OnTimer, el TTimer espera que transcurra este tiempo y recien se llama tu evento. Lo cual genera entre un desfasaje entre el tiempo que le pediste y el momento que llegó. Sumando ese desfasaje tenes tus 10 segundos.

Por lo que veo, tus necesidades no son de controlar el tiempo con gran precición, por lo que podes usar el TTimer tranquilamente.

Para controlar el Tiempo simplemente pudes usar la función Time. Cuando recibes el mesaje desde el socket guardas el tiempo con Time y activas tu TTimer.

Luego en tu evento OnTimer:
Código Delphi [-]
formx.LabelTimer.Caption:= FormatdateTime('hh:mm:ss',Time - TiempoInicial);

y solucionado el problema :D

marceloalegre 01-11-2005 12:30:02

Marteens
 
Muy bien,ha quedado claro, igual al final me habia tirado para el lado del gettickcount con excelentes resultados.

Me queda ahora una duda de lo que dice Ian Marteens:

Código:

Tenga mucho cuidado, si piensa utilizar GetTickCount para este propósito.
 Cada 49 días y fracción, el contador interno sobrepasará el límite de
çcapacidad del tipo Cardinal. Si tenemos la mala fortuna de hacer la primera
llamada antes del suceso, y la segunda después, obtendremos una diferencia
exageradamente grande, suponiendo que utilizamos un Cardinal para el
resultado. Si nuestro algoritmo trata sobre teclas y combos de búsqueda, no
puede pasar nada "excesivamente" malo como castigo. Pero si estamos
controlando algún proceso peligroso... no quiero ni pensar lo que podría
suceder.

Tiene alguna solucion el problema de que gettickcount sobrepasa el limite de capacidad de la variable o hay alguna solucion factible al tema?

vtdeleon 01-11-2005 13:09:41

Saludos
Cita:

Empezado por Dr. Marteens
¿Volvemos al punto de partida? Si queremos una buena medida, en millonésimas de segundo, del tiempo consumido por un algoritmo, podemos utilizar las funciones presentadas de esta manera:
Código Delphi [-]
const
  UnMillon = 1000000;
var
   Frecuencia, X, Y: Int64;
begin
   QueryPerformanceFrequency(Frecuencia);
   QueryPerformanceCounter(X);
   Algoritmo;
   QueryPerformanceCounter(Y);
   ShowMessage(FormatFloat('0,', (Y - X) * UnMillon div Frecuencia));
end;

Suerte

marceloalegre 01-11-2005 18:39:10

Si el lo dice... ha de ser palabra Santa!! :cool:

Gracias y saludos!

gonzalza 28-11-2006 06:02:37

Retardo ml segundos
 
1.tu sabes como generar un retardo de una instruccion de codigo a otra en delphi, sin utilizar timer? ejemplo delay algo asi

2. Y como se genera el codigo de que puede hace un button dentro de un timer, nose como meter el codigo en el timer?

Lepe 28-11-2006 11:27:27

1.- Sleep(2000) se paraliza el hilo de ejecución 2000 milisegudos
Quizás Application.ProcessMessages y Application.HandleMessages pueda servier, no son un retardo en sí, pero hace que mire la cola de mensajes de la aplicación, de esa forma la interfaz no se queda congelada y permite que se haga clicks en otros botones.

2.- Dentro del evento onTimer del TTimer, añade Button1.Click, así ejecutará el código que exista para ese botón.

Saludos

Crandel 28-11-2006 12:07:28

Todo depende de lo que quieras hacer, no hay solucion unica, hay que ver cual se adapta mejor a tu problema.

Depende del tiempo que necesitas entre tus dos segmentos de código y la precisión que te interesa

gonzalza 28-11-2006 16:23:47

gracias, le di un sleep(2000); y me sale Unknown identifier

asi lo meti: ShowMessage('Elmotor gira a la derecha');
Sleep(2000);
ShowMessage('Elmotor ');
Sleep(2000);
ShowMessage('Elmotor gira ');

y lo necesito precisamente para :

ort[888]:=9;
port[888]:=8;
port[888]:=12;
port[888]:=4;
port[888]:=6;
port[888]:=2;
port[888]:=3;
port[888]:=1;
el computador me ejecute esas funciones cuando presione un boton y le pueda cuadra el tiempo en para cada una, lo hice asi sin nada pero al parecer lo ahce muy rapido y termina en el valor inicial el puerto paralelo deberia terminar en 1, pero termina en 9

gonzalza 28-11-2006 23:59:03

creo que ya consegui hacer eso, no he practicado con puerto paralelo pero lo practique con Button.visible y me dio resultado utilizando un timer para cada instrucción con tiempos distinos y con un botton activo los timers.
Por ahi bien, ahora necesito otro boton que cuando haga click me llame al anterior las veces que quiera,ej: 4 veces, es decir: que sea como si hubiera presionado el primer boton 4 veces.


La franja horaria es GMT +2. Ahora son las 02:27:46.

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