visual tick propiedades interval form ejemplo cronometro control c# .net timer precision

tick - timer c# windows form



¿Cuál es la precisión máxima del temporizador en.NET? (8)

Me pregunto cuál es la precisión de la clase Timer en System.Timers, porque es un doble (lo que parece indicar que puede tener fracciones de milisegundos). ¿Qué es?


Los sistemas operativos de escritorio de Windows realmente no son precisos por debajo de aproximadamente 40 ms. El sistema operativo simplemente no es en tiempo real y, por lo tanto, presenta una trepidación significativa no determinista. Lo que eso significa es que, si bien puede informar valores de hasta milisegundos o incluso menores, no se puede contar realmente con que esos valores sean realmente significativos. Entonces, incluso si el intervalo del Temporizador se establece en algún valor de menos de milisegundos, no puede confiar en que los tiempos transcurridos entre la configuración y la activación sean realmente lo que dijo que quería.

Agregue a este hecho que todo el marco bajo el que se ejecuta no es determinista (el GC podría suspenderlo y hacer la recolección del tiempo cuando el temporizador debería disparar) y usted termina con cargas y riesgos grandes tratando de hacer cualquier cosa es crítico en el tiempo


System.Timers.Timer es extraño. Está utilizando un doble como intervalo, pero de hecho llama a Math.Ceiling y arroja el resultado como un int para usar con un System.Threading.Timer subyacente. Su precisión teórica es de 1 ms y no puede especificar un intervalo que exceda los 2.147.483.647 ms. Dada esta información, realmente no sé por qué se usa un doble como parámetro de intervalo.


Hace un par de años descubrí que tiene una precisión de aproximadamente 16 ms ... pero desafortunadamente no recuerdo los detalles.


Puede descubrirlo fácilmente realizando un ciclo que muestrea constantemente la duración del tiempo resultante y compruebe qué granularidad sigue.


Comparé System.Timers.Timer y System.Threading.Timer - ambos dan errores sistemáticos alrededor de 8..16 ms, especialmente en intervalos pequeños (1000 ... 6000 ms). Cada llamada subsiguiente de la rutina del temporizador se produjo con un intervalo mayor desde la primera llamada. Por ejemplo, un temporizador con un intervalo de 2000 ms se dispara en 2000, 4012, 6024, 8036, 10048 milisegundos, etc. (las marcas de tiempo obtenidas de Environment.TickCount y Stopwatch.ElapsedTicks , ambos dan los mismos resultados).


La resolución del temporizador desciende al régimen de 1 ms sin mucho esfuerzo de implementación. Acabo de describir el motivo de la double precisión en esta respuesta . Al configurar el sistema para que se ejecute a 1024 interrupciones por segundo (utilizando la API del temporizador multimedia), el tiempo entre las interrupciones es de 0,9765625 ms. La resolución estándar para cuestiones de tiempo es 100ns. Esos valores se almacenan como enteros. El valor 0,9765625 no se puede almacenar sin perder precisión en un entero con una resolución de 100 ns. El último dígito (5) representa 500 ps. Por lo tanto, la resolución debe ser tres órdenes de magnitud mayor. Almacenar estos valores de tiempo en enteros con una resolución de 100 ps no es posible, ya que un entero de 8 bytes a una resolución de 100 ps se ajustaría después de unos 21350 días o aproximadamente 58 años. Este lapso de tiempo es demasiado corto para ser aceptado por cualquier persona (¡recuerde el escenario del Y2K!).

Consulte la respuesta vinculada para obtener más información sobre los detalles.