Temporizadores .NET, ¿se activan en el intervalo exacto o después del procesamiento + intervalo?

Así que, en realidad, es una pregunta bastante simple.

¿Cómo funciona exactamente el intervalo para System.Timers?

¿Se dispara 1 segundo, cada segundo, independientemente de cuánto tiempo tome el evento de tiempo de espera o requiere que la rutina termine primero y luego reinicie el intervalo?

Así que tampoco:

  1. 1 seg .... 1 seg .... 1 seg y así sucesivamente
  2. 1 seg + tiempo de proceso ... 1 seg + tiempo de proceso ... 1 seg + tiempo de proceso y así sucesivamente

La razón por la que pregunto esto es que sé que mi "procesamiento" toma mucho menos de 1 segundo, pero me gustaría dispararlo cada segundo en el punto (o tan cerca como).

Había estado usando un método Thread.Sleep así:

Thread.Sleep(1000 - ((int)(DateTime.Now.Subtract(start).TotalMilliseconds) >= 1000 ? 0 : (int)(DateTime.Now.Subtract(start).TotalMilliseconds)));

Donde la hora de inicio se registra al inicio de la rutina. El problema aquí es que Thread.Sleep solo funciona en milisegundos. Entonces mi rutina podría reiniciarse a 1000 ms o una fracción más como 1000.0234ms, lo que puede suceder cuando una de mis rutinas toma 0ms de acuerdo con "TimeSpan", pero obviamente ha usado ticks / nanosegundos, lo que significaría que el tiempo está desactivado y no más cada segundo. Si pudiera dormir con garrapatas o nanosegundos, sería genial.

Si el número 1 se aplica a System.Timers, supongo que estoy ordenado. Si no, necesito alguna forma de "dormir" el hilo a una resolución de tiempo más alta, es decir, tics / nanosegundos.

Puede preguntar por qué hago una declaración IF en línea, bueno, a veces el procesamiento puede superar los 1000 ms, por lo que debemos asegurarnos de no crear una cifra negativa. Además, en el momento en que determinamos esto, la hora de finalización ha cambiado ligeramente, no mucho, pero podría hacer que el hilo se demore un poco más, lo que provocará que todo el siguiente se quede inactivo.

Lo sé, lo sé, el tiempo sería insignificante ... pero qué sucede si el sistema se paraliza repentinamente por unos pocos ms ... protegería contra eso en este caso.

actualización 1

Está bien. Así que no me di cuenta de que puedes poner un TimeSpan como valor de tiempo. Entonces usé el siguiente código:

Thread.Sleep(TimeSpan.FromMilliseconds(1000) - ((DateTime.Now.Subtract(start).TotalMilliseconds >= 1000) ? TimeSpan.FromMilliseconds(0) : DateTime.Now.Subtract(start)));

Si estoy en lo cierto, esto debería permitirme repetir el hilo exactamente en 1 segundo, o tan cerca como lo permita el sistema.

preguntado el 28 de agosto de 11 a las 00:08

Windows no es un sistema operativo en tiempo real. Su pregunta implica que le gustaría que fuera así. Si ese es el caso, entonces tendrás que aprender a vivir con la decepción. Los temporizadores son inexactos por naturaleza en un sistema operativo multiproceso como Windows. ¿Qué estás haciendo para que diferencias tan pequeñas sean relevantes? -

No es que tenga que ser en tiempo real. Solo me gustaría que se dispare lo más cerca posible de un segundo en cada iteración, por lo que el método del temporizador es más adecuado. -

@Joan: No es que el solicitud es multiproceso, es que el todo el sistema operativo es multiproceso. Piénselo de esta manera: suponga que de alguna manera el temporizador se dispara exactamente cada segundo en el segundo, garantizado. ¿Qué fuerza misteriosa hace que el sistema operativo no cambiar a un proceso diferente un nanosegundo después de que el controlador de eventos comience a ejecutarse? En el momento en que vuelve a cambiar, ¡podría haber pasado una décima sexta parte de un segundo! -

@Joan cuando duermes un hilo le estás diciendo al SO "Estoy bien para dormir un rato". Puede especificar la precisión que desee, pero estará limitado por los algoritmos del programador de subprocesos. En la mayoría de las máquinas modernas con Windows, la cantidad de subprocesos (la unidad más pequeña de tiempo que un subproceso hace su trabajo antes de ser reprogramado para algo de la misma prioridad que está esperando) es de 15 milisegundos. Por lo tanto, pedir menos que esto es en gran medida inútil. vastas profundidades de complejidad a esto, y si desea conocer el libro de Windows Internals (obtenga el último) de Marc Russinovich es el que debe leer:

@Joan como dije indique sus requisitos y podemos decirle cómo puede lograrlos (tenga en cuenta que algunos requisitos implicarán no usar Windows, algunos requerirán el uso de hardware específico, algunos requerirán que se ejecute en un sistema operativo en tiempo real).

1 Respuestas

SI ha establecido AutoReset = true; entonces su teoría 1 es cierta, de lo contrario tendría que lidiar con ella en código - vea la documentación para Timer en MSDN.

Respondido el 03 de Septiembre de 11 a las 00:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.