2010-11-22 9 views
7

J'utilise DateTime.UtcNow pour mesurer le temps dans mon logiciel et doivent être en mesure de dire si « l'action d'un » produit moins plus de 10 secondes après que « l'action b »Comment détecter si l'heure du système est modifiée? (De .net)

Cependant si la l'heure du système est le changement? Alors, comment puis-je détecter si l'heure du système est modifiée?

Je ne veux pas utiliser un chronomètre que nous avons besoin de fonctionner sur des serveurs avec plus d'un processeur, voir http://kristofverbiest.blogspot.com/2008/10/beware-of-stopwatch.html

Je dois aussi faire face aux machines virtuelles fit une pause et redémarrés, de sorte que le « tick count "A peu de chances de m'être utile.

+0

Pas si sûr que cela ait du sens, un TimeSpan n'est pas affecté par un changement d'horloge.Les changements d'heure et de fuseau horaire sont mis en cache, ils n'affectent pas UtcNow. –

Répondre

8

Vous pouvez utiliser l'événement SystemEvents.TimeChanged pour détecter l'heure modifiée. Cependant, cela ne se déclenchera que si vous avez un messagepump en cours d'exécution - c'est très bien pour les applications client Windows, mais pas pour la plupart des applications serveur (comme les services, les applications web, etc.).

Sinon, vous pouvez utiliser Environment.TickCount - il n'a pas une excellente résolution, mais si vos "10" secondes peuvent être "près de 10 secondes", vous êtes probablement bien. En ce qui concerne la limitation de VM, notez que TickCount survole quand la machine a été suffisamment longue, donc vous devrez gérer cela, éventuellement avec une vérification de santé mentale de DateTime.UtcNow de toute façon. J'utiliserais la combinaison des deux - mais notez qu'il n'y a pas d'autre moyen que de vérifier un serveur de temps externe qui soit précis (qui aura un impact sur la performance) qui fonctionnera dans le cas de la machine virtuelle. Assurez-vous de déterminer ce qui est «assez fiable» avant de passer plus de temps que le problème ne vaut.

1

Vous pouvez utiliser l'événement TimeChanged de la classe SystemEvents pour détecter les changements à l'horloge du système lors de l'exécution:

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

Cela repose sur l'application ayant une boucle de message (je suppose parce que les besoins de message WM_TIMECHANGED à traiter) donc vous aurez besoin d'une forme cachée si c'est une application sans tête service de windows. En ce qui concerne la détection des modifications de l'horloge système pendant la suspension de votre application en raison de la présence d'une machine virtuelle suspendue, tous les paris sont réellement destinés à une solution réellement fiable. Vous pouvez enregistrer périodiquement la dernière fois que vous avez effectué un contrôle, et assurez-vous simplement que le temps n'est pas passé en arrière. Il est probable que cela prendra plus de dix secondes pour suspendre et reprendre une VM de toute façon.

4

Je suggère toujours d'utiliser StopWatch. Si le problème décrit dans Beware of QueryPerformanceCounter existe toujours, vous parlez seulement une différence de quelques millisecondes. Si vous vous inquiétez des temps négatifs (quelque chose que je n'ai jamais vu, et j'utilise StopWatch beaucoup de temps à de très petits intervalles), puis traitez n'importe quoi entre -1 milliseconde et -1 000 millisecondes comme zéro. L'utilisation de DateTime.Now ou DateTime.UtcNow pour tout type de synchronisation va vous causer des problèmes si quelqu'un change la date/heure sur la machine. Vous devez utiliser quelque chose qui est complètement interne à l'ordinateur et ne peut pas être changé. StopWatch est le plus fiable que j'ai trouvé.

0

Je voudrais comparer la différence de temps du système avec une horloge monotique entre 2 intervalles de temps. Si la différence est supérieure à une certaine tolérance que quelqu'un a changé la date et l'heure sur votre machine

Questions connexes