Как определить, изменилось ли системное время?(из .net) - PullRequest
7 голосов
/ 22 ноября 2010

Я использую DateTime.UtcNow для измерения времени в моем программном обеспечении, и мне нужно знать, происходит ли «действие a» менее чем через 10 секунд после «действия b»

Однако что если системное времятакое изменение?Итак, как мне определить, изменилось ли системное время?

Я не хочу использовать секундомер, так как нам нужно работать на серверах с более чем одним процессором, см. http://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

Мне также нужно справиться с приостановкой и перезапуском виртуальных машин, поэтому «подсчет тиков» вряд ли будет мне полезен.

Ответы [ 4 ]

9 голосов
/ 22 ноября 2010

Вы можете использовать событие SystemEvents.TimeChanged для определения измененного времени. Однако, это сработает, только если у вас запущен насос сообщений - это хорошо для клиентских приложений Windows, но не так много для большинства серверных приложений (таких как сервисы, веб-приложения и т. Д.).

В противном случае вы можете использовать Environment.TickCount - у него нет отличного разрешения, но если ваши "10" секунд могут быть "почти 10 секунд", вы, вероятно, в порядке. Что касается ограничения виртуальной машины, обратите внимание, что TickCount переворачивается, когда машина проработала достаточно долго, поэтому вам придется справиться с этим, возможно, с проверкой работоспособности DateTime.UtcNow в любом случае.

Я бы использовал комбинацию обоих - но учтите, что нет абсолютно точного способа, кроме проверки какого-либо внешнего точного сервера, который известен точно (который будет иметь перфорированное воздействие), который будет работать в случае с ВМ в любом случае ... убедитесь, что вы определили, что является «достаточно надежным», прежде чем тратить больше времени, чем стоит проблема.

4 голосов
/ 22 ноября 2010

Я бы все равно предложил использовать StopWatch.Если проблема, описанная в Остерегайтесь QueryPerformanceCounter , все еще существует, вы говорите только с разницей в несколько миллисекунд.Если вы беспокоитесь о негативных временах (то, чего я никогда не видел, и я часто использую StopWatch для некоторых довольно небольших интервалов), тогда обработайте что-нибудь между -1 миллисекундами и -1000 миллисекундами как ноль.1006 * Использование DateTime.Now или DateTime.UtcNow для любого типа синхронизации может вызвать проблемы, если кто-либо изменит дату / время на машине.Вы должны использовать что-то полностью внутреннее для компьютера и не может быть изменено.StopWatch самый надежный из всех, что я нашел.

1 голос
/ 22 ноября 2010

Вы можете использовать событие TimeChanged класса SystemEvents для обнаружения изменений системных часов во время выполнения:

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

Это зависит от вашего приложения, имеющего цикл сообщений (я полагаю,потому что сообщение WM_TIMECHANGED должно быть обработано), поэтому вам потребуется скрытая форма, если это приложение без заголовка, например, служба Windows.

Что касается обнаружения изменений в системных часах, пока ваше приложение приостановлено из-за нахождения наприостановлена ​​виртуальная машина - все ставки действительно на действительно надежное решение.Вы можете периодически записывать последний раз, когда вы выполняли проверку, и просто убедиться, что время не ушло в обратном направлении.В любом случае для приостановки и возобновления работы виртуальной машины может потребоваться более десяти секунд.

0 голосов
/ 20 июля 2017

Я бы сравнил разницу во времени системы с монотонными часами между двумя временными интервалами.Если разница больше допустимого отклонения, чем кто-либо, измените дату и время на вашем компьютере

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...