2017-09-19 7 views
-1

J'appelle deux minuteurs dans un WinForm pour différents processus, tous les deux utilisent le même format try-catch. Cela fonctionne bien pendant les premiers jours, puis commence à devenir lent. Je peux voir une certaine charge sur le serveur. Mon événement de minuterie est-il correct? Cet événement ne met-il pas beaucoup de poids?Comment savoir si mon minuteur Windows fonctionne parfaitement et ne cause aucune fuite de mémoire

Dans mon try-catch, je n'arrête la minuterie que si mon code attrape une exception. Je doute sinon d'exception, et mon temps n'est pas arrêté. Si je démarre la minuterie la deuxième fois, cela mettra plus de charge ou sa réinitialisation. S'il vous plaît donnez votre précieux conseil. Merci beaucoup d'avance.

Mon code est ci-dessous.

minuterie 1 Tick:

private void timerMain_Tick(object sender, EventArgs e) 
{ 
    try 
    { 
     // Retrieve some status and Update 
    } 
    catch (Exception ex) 
    { 
     timerMain.Stop(); 
     MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex); 
    } 
    finally 
    { 
     timerMain.Start(); 
    } 
} 

minuterie 2 Tick:

private void timerWorkStep_Tick(object sender, EventArgs e) 
{ 
    try 
    { 
     // Retreive Some value from web proxy and set to label 
    } 
    catch (Exception ex) 
    { 
     timerWorkStep.Stop(); 
     MessageBoxHelper.ShowException(LanguagePack.LanguageHelper.GetString(GlobalParameters.Language, "Error_ExecutionEx"), ex); 
    } 
    finally 
    { 
     timerWorkStep.Start(); 
    } 
} 
+0

Il ne semble pas que quelque chose ne va pas dans la configuration de la minuterie. Il est possible que toute fuite de mémoire qui peut se produire existe dans tout ce que vous faites dans la partie try de votre code. Qu'est-ce qui vous a fait penser que la minuterie est le problème? –

+0

Merci pour votre commentaire. Dans mon cas, j'ai appelé finalement timer.start même si je n'arrête pas le timer sauf l'exception. donc je me suis senti, il peut être plus de boucle et minuterie exécutera plusieurs instances. – Mdyahiya

+0

Si vous voulez que la personne à qui vous répondez soit notifiée, vous devez les mentionner comme suit: @ninjacoder –

Répondre

0

j'ai raté le problème, mais il m'a été signalé dans les commentaires par l'OP alors voici ma réponse. Je ne dirais pas que vous avez exactement une fuite de mémoire parce que vous libérez finalement la mémoire et les ressources que vous utilisez, mais comme vous l'avez souligné dans le commentaire, je serais certainement d'accord que l'arrêt de votre minuterie dans la prise et toujours le commencer dans le dernier pourrait certainement faire courir votre tic plus souvent que sur un intervalle fixe. Si vous exécutez l'exemple ci-dessous, vous verrez ce que je veux dire.

minuterie en cours De nombreux Tiques At Once Exemple

void Main() 
{ 
    _timer = new System.Timers.Timer(100); 

    _timer.Elapsed += Timer_Elapsed; 

    _timer.Start(); 
} 

private void Timer_Elapsed(object sender, EventArgs e) 
{ 
    try 
    { 
     for (int i = 0; i < 15; i++) 
     { 
      Console.Write(i + " "); 
      Thread.Sleep(10); 
     } 
     Console.WriteLine(); 
    } 
    catch (Exception ex) 
    { 
     _timer.Stop(); 
     Console.WriteLine(ex.Message); 
    } 
    finally 
    { 
     _timer.Start(); 
    } 
} 

private System.Timers.Timer _timer; 

J'utilise des minuteries sur une base régulière pour la plupart de mes services Windows et nous avons adopté le modèle de l'arrêt de la minuterie comme la première chose dans la tique et le redémarrer une fois la tique terminée. Le problème avec le code directement en dessous qu'il ne fonctionne pas à chaque intervalle défini en raison du temps qu'il faut pour traiter effectivement

Motif Timer

private void Timer_Elapsed(object sender, EventArgs e) 
{ 
    try 
    { 
     _timer.Stop(); 

     //some work 
    } 
    catch(Exception ex) 
    { 

    } 
    finally 
    { 
     _timer.Start(); 
    } 
} 

Si vous voulez plus d'une course fiable toutes les heures à 5 après l'heure, vous aurez besoin de faire quelque chose comme ceci:

Motif Timer sur Intervalle fiable

public class NextRunCalculator 
{ 
    public double CalculateTimeUntilNextRun() 
    { 
     List<int> processingMinutes = new List<int> { ServiceConstants.RunMinute5 };//this is a list of minutes during the hour you want the service to run 

     int t = int.MaxValue; 
     foreach (var processingMinute in processingMinutes) 
     { 
      var minutesRemaining = processingMinute - DateTime.Now.Minute; 

      if (minutesRemaining <= 0) 
      { 
       minutesRemaining = 60 + minutesRemaining;//change 60 to however often you want the timer to run 
      } 

      if (minutesRemaining < t) 
      { 
       t = minutesRemaining; 
      } 
     } 

     return TimeSpan.FromMinutes(t).TotalMilliseconds; 
    } 
} 

private void Timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    _timer.Stop(); 

    //do work 

    _timer.Interval = _nextRunCalculator.CalculateTimeUntilNextRun(); 
    _timer.Start(); 
} 
+0

Merci pour les commentaires. Même moi-même pensé même et mis activer false au début de mon code et définissez vrai à enfin essayer, je vais surveiller la performance des prochains jours et vous mettra à jour. Remarque: Ma minuterie doit fonctionner en continu lorsque le formulaire est actif et définir l'intervalle 15 secondes. L'espoir sera plus performant. Encore une fois merci pour la réponse détaillée. – Mdyahiya