2010-07-21 7 views
2

J'ai utilisé System.Timer pour exécuter un service Windows mais j'ai rencontré le problème où la minuterie ne se déclenche pas aléatoirement. Je l'ai vérifié hier et il n'avait pas tiré pendant plus de 2 heures quand il a fallu tirer toutes les 10 minutes. J'ai lu cela sur Google et apparemment c'est un problème connu, la réponse étant de passer à Threading.Timer. Je n'ai pas utilisé cela avant donc je cherchais un peu de perspicacité. Mon code actuel est comme suit:Convertir C# System.Timer en Threading.Timer

using System; 
using System.Timers; 
using System.ServiceProcess; 

namespace Code 
{ 
public partial class Service : ServiceBase 
{ 
    Timer timer = new Timer(); 

    public Service() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); 
     timer.Interval = 10000; 
     timer.Enabled = true; 
    } 

    protected override void OnStop() 
    { 
     timer.Enabled = false; 
    } 

    private void OnElapsedTime(object source, ElapsedEventArgs e) 
    { 
     timer.Enabled = false; 
     // Run system code here 
     timer.Interval = 600000; 
     timer.Enabled = true; 
    } 
} 

}

Fondamentalement, cela fonctionne normalement bien. Le système démarre la minuterie et se déclenche après 10 secondes. Il arrête la minuterie, fait le travail, réinitialise le minuteur pendant 10 minutes et le permet. Pour la plupart cela fonctionne toujours, mais comme mentionné précédemment décide aléatoirement d'arrêter de travailler, probablement en raison des ressources du système, etc ..

Si quelqu'un peut m'aider à convertir cela en Threading.Timer, il serait apprécié.

Merci, Chris

+0

Avant de proposer des changements, une chance de « timer.Enabled = true » ne se fait frapper à cause d'une exception levée dans la " // Exécutez le code système ici "partie? –

+2

Donc, vous avez examiné le code sur http://msdn.microsoft.com/fr-fr/library/system.threading.timer.aspx premier droit? – Codesleuth

+0

" Probablement en raison de Pourquoi une minuterie s'arrêterait-elle de fonctionner? Je dirais que Willem a probablement raison - si vous avez si peu de ressources que votre machine ne peut pas lancer une minuterie, vous auriez remarqué plus que votre service cassé ... –

Répondre

2

Voilà ma meilleure estimation - pas le temps de le tester, désolé :(

using System; 
using System.Threading; 
using System.ServiceProcess; 

namespace Code 
{ 
    public partial class Service : ServiceBase 
    { 
     Timer timer; 
     AutoResetEvent autoEvent; 
     bool stopped = true; 

     public Service() 
     { 
      InitializeComponent(); 
     } 

     protected override void OnStart(string[] args) 
     { 
      stopped = false; 
      TimerCallback tcb = new TimerCallback(OnElapsedTime); 
      timer = new Timer(tcb, null, 10000, 600000); 
     } 

     protected override void OnStop() 
     { 
      stopped = true; 
      timer.Dispose(); 
     } 

     private void OnElapsedTime(Object stateInfo) 
     { 
      if (stopped) 
       return; 

      // Run system code here 
     } 
    } 
} 
+0

Je suppose que l'OP veut 'Timeout.Infinite' comme intervalle et redémarrer le timer chaque fois en utilisant 'Change (600000, Timeout.Infinite)' chaque fois que ** System Code ** est fini (ou peut-être c'est l'erreur qu'il fait dans son exemple - qui sait :-D). –

+0

L'utilisation du constructeur n'est-elle pas correcte? Je viens de vérifier sur la page MSDN et je pensais que je l'ai eu raison: s – Codesleuth

+0

Ont juste mis en œuvre ce code et il semble fonctionner très bien. Je définis l'intervalle pour changer chaque fois qu'il se déclenche afin qu'il ne chevauche pas une méthode déjà en cours d'exécution. Comme Jaroslav mentionné j'ai ajouté dans ce qui suit dans l'appel de temps écoulé: timer.Change (Timeout.Infinite, Timeout.Infinite); et ensuite timer.Change (600000, Timeout.Infinite); – Chris