2008-11-04 10 views
2

Dans une application de test étroitement bouclée qui imprime la valeur de DateTime.UtcNow.Ticks, je remarque que la valeur va sauter une quantité remarquable une fois toutes les heures. Regardez attentivement les données exemple suivant:DateTime.UtcNow.Ticks saute parfois une quantité remarquable

1:52:14.312 PM - 633614215343125000 
1:52:14.359 PM - 633614215343593750 
1:52:14.421 PM - 633614215344218750 
1:52:14.468 PM - 633614215344687500 
1:52:14.515 PM - 633614215998593750 <-- WAY different 

Le delta est 653906250 tiques (65.390 secondes). La seule raison que je peux trouver est que le service de temps de Windows effectue une synchronisation de sous mes pieds.

  • Y at-il des experts là-bas qui peuvent le confirmer?
  • Dériver une minute ou deux en l'espace d'une heure me semble assez mauvais, mais est-ce le cas ici?
+0

Comment consignez-vous l'heure à gauche? Cela ne semble pas avoir le même saut, ce qui est assez étrange ... –

+0

Quel code produit la sortie? Quelles mesures ont été prises pour assurer la cohérence de l'intervalle entre les appels? Utilisez-vous Thread.Sleep()? –

Répondre

0

Pouvez-vous afficher un code pour afficher comment vous avez généré cette donnée? Et fournir des détails sur la machine sur laquelle vous l'utilisez?

En utilisant ce qui suit, je ne comprends pas ce que vous obtenez.

 for (int i = 0; i < 10; i++) 
     { 

      Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + " - " + DateTime.UtcNow.Ticks.ToString()); 

      Thread.Sleep(10); 
     } 
+0

La question dit que cela n'arrive qu'une fois toutes les heures ... vous avez peu de chance de le voir dans le temps pris par 10 itérations! –

2

En fait, juste en cours d'exécution des essais à partir de cette boucle:

static DateTime past = DateTime.UtcNow; 
    static void PrintTime() 
    { 
     while (stopLoop == 0) 
     { 
      DateTime now = DateTime.UtcNow; 
      Console.WriteLine("{0} - {1} d: {2}", now, now.Ticks, now - past); 
      Program.past = now; 
      Thread.Sleep(2000); 
     } 
    } 

Si j'ai changé le temps d'horloge de mon système entre les deux appels, le delta sauteraient en conséquence. Donc, si vous avez une synchronisation de l'heure en cours d'exécution ou un autre processus qui affecte l'heure du système, cela sera reflété dans la sortie.

0

Esteban a raison, une modification de l'horloge système entraînerait une modification du temps delta entre les scrutins consécutifs. Le service Windows Time effectue-t-il ces modifications toutes les heures? Dérive une minute au large dans une heure probable?

Pour que cela se produise sur votre machine, si vous avez suivi le delta en cas de changement entre les vérifications, vous pouvez définir un point d'arrêt conditionnel en cas de changement inhabituellement élevé de delta.

long delta = 0; 
long ticks = 0; 
long lastTicks = DateTime.UtcNow.Ticks; 
while (true) 
{ 
    ticks = DateTime.UtcNow.Ticks; 
    delta = ticks - lastTicks; 
    lastTicks = ticks; 
    // Conditional breakpoint: delta > 100000000 Is True 
    Console.WriteLine("{0} - {1}", ticks, delta); 
} 
0

La sortie d'origine a été interceptée dans DebugView. Mon application gérée effectuait un appel p/invoke OutputDebugString, en sortant simplement DateTime.UtcNow.Ticks à partir d'une boucle serrée dans un thread appelé Thread.Sleep (1).

 
System information for \\JLECOURSXP: 
Uptime:     6 days 6 hours 22 minutes 53 seconds 
Kernel version:   Microsoft Windows XP, Multiprocessor Free 
Product type:    Professional 
Product version:   5.1 
Service pack:    3 
Kernel build number:  2600 
Registered organization: 
Registered owner:   setup 
Install date:    6/15/2007, 3:35:29 PM 
IE version:    7.0000 
System root:    C:\WINDOWS 
Processors:    2 
Processor speed:   2.9 GHz 
Processor type:   Intel(R) Pentium(R) D CPU 
Physical memory:   3070 MB 
Video driver:    RADEON 9250 - Secondary 
1

Ehm ...

Comment pouvez-vous mesurer le temps de cette façon quand vous ne pouvez pas dire à coup sûr que vous n'êtes pas appeler un certain appel système de blocage pendant ce temps (comme, potentiellement Console.WriteLine) ?

Afin d'avoir un « test de travail » vous devez au moins vous assurer:

  • RIEN est en cours d'exécution d'autre sur votre machine
  • La priorité processus/thread est défini sur Élevé ou quelque chose comme
  • Appelez PAS d'appel système ...Faites uniquement les tâches computationl
  • Définir l'affinité de fil à une unité centrale de traitement spécifique pour vous si vous avez pas arbitrées entre les unités centrales

Même le faire, le système d'exploitation serait de temps en temps (15ms sur un ordinateur Windows Dual- OS de bureau de base par exemple) préempter votre fil .... Et vous pourriez toujours certainement voir ce genre de "saut" dans UTC Time-Stamp.

Juste allant de Userspace à l'espace noyau (pendant un appel Préemption/système) et à l'arrière, sans faire aucun travail du noyau substantiel, prendrait ~ 1000 cycles CPU ...

Si vous traitez est mis en état d'attente (en appelant des E/S bloquantes) il pourrait même être BEAUCOUP bien pire ...

Donc je ne reçois pas vraiment votre "test". OMI c'est parfaitement normal.

+0

La sortie ci-dessus a été présentée toutes les 40-60ms et après une heure ou deux de fonctionnement, a montré ce saut de 65 secondes dans ce que DateTime.UtcNow.Ticks (basé sur GetSystemTimeAsFileTime api) est de retour. Cela ne peut pas être quelque chose de bloquant, de mettre en attente ou d'être préempté. –

Questions connexes