vb.net - Temporizador de Windows preciso? System.Timers.Timer() está limitado a 15 mseg
(6)
En System.Diagnostics, puede usar la clase Cronómetro .
Necesito un temporizador preciso para conectar una aplicación de Windows a un equipo de laboratorio.
Usé System.Timers.Timer () para crear un temporizador que funciona cada 10 mseg, pero este reloj funciona lentamente. Por ejemplo, 1000 tics con un intervalo de 10 mseg deben tomar 10 segundos del reloj de pared, pero en realidad toma más de 20 segundos del reloj de pared (en mi PC). Supongo que esto es porque System.Timers.Timer () es un temporizador de intervalo que se restablece cada vez que transcurre. Como siempre tardará un tiempo entre el momento en que transcurre el tiempo del temporizador y el momento en que se restablece (a otros 10 ms), el reloj funcionará lentamente. Esto probablemente sea correcto si el intervalo es grande (segundos o minutos) pero inaceptable por intervalos muy cortos.
¿Hay una función en Windows que activará un procedimiento cada vez que el reloj del sistema cruza un límite de 10 mseg (o lo que sea)?
Esta es una aplicación de consola simple.
Gracias
Norma
ACTUALIZACIÓN: System.Timers.Timer () es extremadamente inexacto para intervalos pequeños.
Escribí un programa simple que contó 10 segundos de varias maneras:
Intervalo = 1, Recuento = 10000, Tiempo de ejecución = 160 seg, mseg por intervalo = 16
Intervalo = 10, cuenta = 1000, tiempo de ejecución = 16 segundos, mseg por intervalo = 15
Intervalo = 100, Cuenta = 100, Tiempo de ejecución = 11 segundos, mseg por intervalo = 110
Intervalo = 1000, cuenta = 10, tiempo de ejecución = 10 segundos, mseg por intervalo = 1000
Parece que System.Timers.Timer () no puede marcar más rápido que aproximadamente 15 mseg, independientemente de la configuración del intervalo.
Tenga en cuenta que ninguna de estas pruebas parecía utilizar un tiempo de CPU medible, por lo que el límite no es la CPU, solo una limitación .net (¿error?)
Por ahora, creo que puedo vivir con un temporizador inexacto que desencadena una rutina cada 15 mseg o más y la rutina obtiene un tiempo de sistema preciso. Un poco extraño, pero ...
También encontré un producto shareware ZylTimer.NET que dice ser un temporizador .net mucho más preciso (resolución de 1-2 msec). Esto puede ser lo que necesito. Si hay un producto, es probable que haya otros.
Gracias de nuevo.
En la superficie de la misma, la respuesta es algo así como "temporizador de alta resolución", sin embargo, esto es incorrecto. La respuesta requiere una generación de tics regular y la API de contador de rendimiento de alta resolución de Windows no genera ese tic.
Sé que esto no es una respuesta en sí, pero la respuesta popular a esta pregunta hasta ahora es lo suficientemente errónea como para que sienta que un simple comentario sobre ella no es suficiente.
Hay un buen escrito en MSDN: implementar un proveedor de tiempo de alta resolución y actualización continua para Windows
Aquí está el código fuente de muestra para el artículo (C ++).
La limitación viene dada por los latidos del sistema. Esto normalmente tiene un valor predeterminado de 64 latidos / s que es 15.625 ms. Sin embargo, hay formas de modificar estas configuraciones de todo el sistema para lograr resoluciones de temporizador de hasta 1 ms o incluso a 0.5 ms en las plataformas más nuevas:
Yendo para una resolución de 1 ms mediante la interfaz del temporizador multimedia (
timeBeginPeriod()
):Consulte Obtención y configuración de la resolución del temporizador .
Ir a una resolución de 0.5 ms mediante
NtSetTimerResolution()
:Consulte dentro de los temporizadores de alta resolución de Windows NT .
Puede obtener una resolución de 0.5 ms mediante la API oculta NtSetTimerResolution()
.
He dado todos los detalles en esta respuesta SO.
Necesita usar un temporizador de alta resolución como QueryPerformanceCounter
Por encima de mi cabeza, podría sugerir que se ejecute un hilo que duerme en su mayoría, pero cuando se despierta, comprueba un QueryPerformanceCounter
ejecución y ocasionalmente desencadena su procedimiento.