2010-11-22 10 views
7

Estoy usando DateTime.UtcNow para medir el tiempo en mi software y necesito saber si la "acción a" ocurre menos de 10 segundos después de "acción b"¿Cómo puedo detectar si la hora del sistema ha cambiado? (de .net)

¿Qué ocurre si el el tiempo del sistema es cambio? Entonces, ¿cómo puedo detectar si la hora del sistema ha cambiado?

No deseo usar un cronómetro, ya que necesitamos para funcionar en servidores con más de una CPU, consulte http://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

También necesito para hacer frente a las máquinas virtuales que pausar y reiniciar, por lo que el “conteo de garrapatas "Es poco probable que me sea útil.

+0

No estoy tan seguro de que tenga sentido, un TimeSpan no se ve afectado por un cambio de reloj.Los cambios en el horario de verano y en la zona horaria se almacenan en caché, no afectan a UtcNow. –

Respuesta

8

Puede usar el evento SystemEvents.TimeChanged para detectar el tiempo cambiado. Sin embargo, esto solo se activará si tiene activada una bomba de mensajes; esto está bien para las aplicaciones cliente de Windows, pero no tanto para la mayoría de las aplicaciones de servidor (como servicios, aplicaciones web, etc.).

De lo contrario, puede usar Environment.TickCount - no tiene una resolución excelente, pero si sus "10" segundos pueden ser "casi 10 segundos", probablemente esté bien. En cuanto a la limitación de VM, tenga en cuenta que TickCount gira cuando la máquina ha estado activa durante el tiempo suficiente, por lo que tendrá que manejar eso, posiblemente con un chequeo de cordura DateTime.UtcNow en ambos sentidos.

Utilizaría la combinación de ambos, pero tenga en cuenta que no hay otra manera absolutamente precisa que no sea verificar algún servidor horario externo conocido (que tendrá un impacto de perforación) que funcionará en el caso de VM de todos modos. . Asegúrate de determinar qué es "lo suficientemente confiable" antes de dedicar más tiempo de lo que vale el problema.

1

Usted puede utilizar el evento TimeChanged de la clase SystemEvents para detectar cambios en el reloj del sistema en tiempo de ejecución:

http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.timechanged.aspx

Esto se basa en la aplicación que tiene un bucle de mensajes (supongo que debido a que las necesidades de mensajes WM_TIMECHANGED para ser procesado) por lo que necesitará una forma oculta si se trata de una aplicación sin cabeza, por ejemplo servicio de ventanas.

En cuanto a la detección de cambios en el reloj del sistema, mientras que su aplicación se suspende debido a estar en una máquina virtual suspendida, todas las apuestas están desactivadas realmente para una solución verdaderamente confiable. Puede registrar periódicamente la última vez que realizó un control, y solo asegurarse de que el tiempo no haya retrocedido. Es probable que tarde más de diez segundos en suspender y reanudar una máquina virtual de todos modos.

4

Todavía sugeriría usar StopWatch. Si todavía existe el problema descrito en Beware of QueryPerformanceCounter, solo está hablando una diferencia de unos pocos milisegundos. Si te preocupan los tiempos negativos (algo que nunca he visto, y uso StopWatch mucho para cronometrar algunos intervalos bastante pequeños), entonces trata cualquier cosa entre -1 milisegundo y -1,000 milisegundos como cero.

El uso de DateTime.Now o DateTime.UtcNow para cualquier tipo de sincronización le causará problemas si alguien cambia la fecha/hora en la máquina. Tienes que usar algo que es completamente interno a la computadora y no se puede cambiar. StopWatch es el más confiable que he encontrado.

0

Yo compararía la diferencia de tiempo del sistema con un reloj monótono entre 2 intervalos de tiempo. Si la diferencia es mayor que alguna tolerancia, alguien cambió la fecha y la hora en su máquina

Cuestiones relacionadas