2016-02-04 2 views
2

J'utilise OpenNETCF Timer2 (et précédemment System.Threading.Timer) dans cet exemple. Le minuteur se comporte très bizarre. Après environ 7-8 heures. Il fait quelques appels aléatoires de la fonction d'événement Timer avec un intervalle de 2 secondes au lieu de 1 seconde. Et se comporte normalement pour les prochaines 7-8 heures. Veuillez guider, j'ai essayé System.Threading.Timers mais cela semble appeler l'événement de temporisateur par 2 secondes au lieu de 1 seconde pour chaque 2 minutes. Comment régler ce problème?OpenNETCF.Timers.Timer2 et System.threading.timer mauvais appel d'événement de temporisation après 7-8 heures

public partial class Form1 : Form 
{ 
    private OpenNETCF.Timers.Timer2 mTimer2; 
    private DateTime mLastSampleTime; 
    private Int32 Interval; 
    private Double ActualInterval; 
    private long ActualTickInterval;`enter code here` 
    StreamWriter file; 
    Boolean firstRun = true; 

    //private Timer sysTimer; 

    public Form1() 
    { 
     InitializeComponent(); 
     /// <summary> 
     /// Timer object for Windows CE environment. 
     /// </summary> 
     /// 

     // This text is always added, making the file longer over time 
     // if it is not deleted. 
     file = System.IO.File.AppendText("TimerLog.txt"); 




     mTimer2 = new OpenNETCF.Timers.Timer2(1000);//1000 for actual test 
     mTimer2.AutoReset = true; 
     mTimer2.Elapsed += Timer2Event; 
     mTimer2.Start(); 
     file.WriteLine("TImer Started"); 

    } 


    private void Timer2Event(object sender, 
     OpenNETCF.Timers.ElapsedEventArgs e) 
    { 
     try 
     { 

      DateTime now = DateTime.UtcNow; 

      if (!firstRun) //do not calculate difference if first run 
      { 
       //ActualInterval = ((now - mLastSampleTime).TotalMilliseconds);//Difference between previous timestamp and current (in milliseconds) 
       ActualTickInterval = ((now - mLastSampleTime).Ticks);//Difference between previous timestamp and current (in ticks) 
       Interval = Convert.ToInt32((now - mLastSampleTime).TotalSeconds);//Interval as used in LAMP code 

       if (Interval >= 2) file.Write("-------->");//if Interval is 2 seconds, Mark it. 
       file.Write("UTC Now: " + now.ToString() +" Current Tick: "+now.Ticks.ToString() +" Actual Interval: " + ActualInterval + " Actual Tick Difference: "+ActualTickInterval.ToString()+" Deviation (Ideal=0) "+(ActualTickInterval-10000000).ToString()+"\r\n"); 
       file.Flush();  
      } 
      else 
      { 
       firstRun = false; 
      } 
      mLastSampleTime = now; 
     } 
     catch (Exception exp) 
     { 
      file.Write("Logging Failed " + DateTime.UtcNow.ToString() + " exception: " + exp.Message+"\r\n"); 
     } 
    } 



    } 

} 

La différence de tic passe directement de 10 000 000 à 2 000 000 pour ces cas spécifiques. Et la différence de tick suivante est 0. I.E 2 lignes dans le fichier journal ont le même horodatage.

Répondre

3

Il y a un problème dans votre logique de test qui pourrait expliquer le comportement que vous voyez.

Sous Windows CE est très rare - je veux dire super-ultra-rare dans mon expérience - que l'horloge du système a des résultats plus fins que 1 seconde complète. En fait, il est très souvent lié à un RTC matériel qui ne donne qu'une résolution de 1 seconde. Cela signifie que vos maths utilisant DateTime.Ticks ne sont pas utiles, et une différence de, disons 1: 00.999 et 1: 02: 001, apparaîtra comme un écart de 2 secondes, pas 1.002. Changez votre logique pour utiliser Environment.TickCount pour mesurer le temps écoulé entre les ticks et vous devriez voir les nombres juste près de 1000 à chaque fois et cela éliminera le potentiel de l'artefact que vous voyez.

EDIT

L'objet Timer2, comme les formes minuterie intégrée, basée sur la tique de la pompe de message Windows et ne vise pas à être très précis. 1000ms +/- quelques dizaines ne me surprend pas du tout.

Si vous avez besoin de plus de précision, vous devez utiliser une minuterie de filetage ou une minuterie de haute précision (disponible dans le SDF sous l'espace de noms OpenNETCF.Timers). Même avec ceux-ci, cependant, vous devez être conscient que vous utilisez un environnement de gestion des déchets géré, donc il n'y a absolument aucune garantie que vous obtiendrez des tics précis de 1000ms. Si vous avez besoin d'un comportement absolument déterministe, vous devez écrire la partie qui l'exige en C, et savoir comment atteindre le déterminisme même là.

+0

Merci, j'ai utilisé Environment.TickCount. La différence de tick montre 1013 MS au lieu de 1000 MS pour les cas (où timer saute 2 secondes). La différence de tique consécutive est de 987 MS. (où l'horodatage se répète) Ensuite, il normalise à 1000MS pour les 7 prochaines heures. Dans certains cas, même avec 2 secondes d'intervalle ont exactement 1000MS. Pouvez-vous expliquer pourquoi cela arrive? Ma conjecture est Environment.Ticks est seulement précis à 1000MS pour chaque seconde. Dans des cas comme celui-ci, la différence est de l'ordre de ns ou ms. Est-ce correct? Je suis sur le point d'utiliser la classe Stopwatch pour ça. –