2010-12-30 5 views
3

J'ai un service de fenêtre qui lit un fichier son à une heure spécifiée, donc pour cela j'ai pris Timer mais son événement Tick n'est jamais déclenché, il fonctionne dans l'application WinForm.L'événement Timer Timer n'est pas appelé dans le service Windows

est Ci-dessous l'extrait de code de mon service ...

public partial class ClockService : ServiceBase 
{ 
    private TimeSpan _alarmTime = new TimeSpan(9, 55, 0); 
    private int _snoozeTime = 2; // 2 minutes 
    private int _repeatCounter = -1; 
    private const int ALARM_REPETITION = 5; 
    private string _alarmSoundPath = @"C:\Sound\default.wav"; 
    private string _alarmLogPath = @"C:\Sound\log.txt"; 

    public ClockService() 
    { 
     InitializeComponent(); 
     alarmTimer.Enabled = true; 
    } 

    protected override void OnStart(string[] args) 
    { 
     using (FileStream fileStream = new FileStream(_alarmLogPath, FileMode.OpenOrCreate)) 
     { 
      using (StreamWriter writer = new StreamWriter(fileStream)) 
      { 
       writer.WriteLine("Service has started at {0}", DateTime.Now); 
      } 
     } 
    } 

    protected override void OnStop() 
    { 
     using (FileStream fileStream = new FileStream(_alarmLogPath, FileMode.OpenOrCreate)) 
     { 
      using (StreamWriter writer = new StreamWriter(fileStream)) 
      { 
       writer.WriteLine("Service has stopped at {0}", DateTime.Now); 
      } 
     } 
    } 

    private void alarmTimer_Tick(object sender, EventArgs e) 
    { 
     using (FileStream fileStream = new FileStream(_alarmLogPath, FileMode.OpenOrCreate)) 
     { 
      using (StreamWriter writer = new StreamWriter(fileStream)) 
      { 
       writer.WriteLine("Alarm time is: {0}", _alarmTime); 
      } 
     } 

     TimeSpan currentTime = new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes, DateTime.Now.TimeOfDay.Seconds); 


     if (currentTime == _alarmTime) 
     { 
      using (FileStream fileStream = new FileStream(_alarmLogPath, FileMode.OpenOrCreate)) 
      { 
       using (StreamWriter writer = new StreamWriter(fileStream)) 
       { 
        writer.WriteLine("Alarm time is: {0} and current time is: {1}", _alarmTime, currentTime); 
       } 
      } 

      _alarmTime = _alarmTime.Add(new TimeSpan(0, _snoozeTime, 0)); 
      _repeatCounter++; 

      if (File.Exists(_alarmSoundPath)) 
      { 
       SoundPlayer player = new SoundPlayer(_alarmSoundPath); 
       player.PlayLooping(); 
      } 

     } 

     if (_repeatCounter == ALARM_REPETITION) 
     { 
      _alarmTime = _alarmTime.Subtract(new TimeSpan(0, (ALARM_REPETITION * _snoozeTime), 0)); 
      _repeatCounter = 0; 
     } 

    } 
} 

Pour vous assurer que je l'ai fait tout correctement, voici ma méthode InitializeComponent

private void InitializeComponent() 
      { 
       this.components = new System.ComponentModel.Container(); 
       this.alarmTimer = new System.Windows.Forms.Timer(this.components); 
       this.alarmTimer.Enabled = true; 
       this.alarmTimer.Interval = 1000; 
      this.alarmTimer.Tick += new System.EventHandler(this.alarmTimer_Tick); 
     this.ServiceName = "PravoAlarmService"; 
    } 

S'il vous plaît quelqu'un a un regard et me guider ... problème est l'événement tique n'a jamais tiré ..

Répondre

10

Essayez d'utiliser le System.Timers.Timer à la place.

this.alarmTimer = new System.Timers.Timer(); 

Le System.Windows.Forms.Timer - comme son nom l'indique - œuvres dans formes applications, mais pas quelque chose comme un service NT.

0

Ne pas utiliser un System.Windows.Forms.Timer, utilisez un System.Threading.Timer.

Un service n'est pas une forme.

1

Je pense que System.Timers.Timer est un meilleur choix:

Timer _timer = new Timer(); 
// In miliseconds 60000 = 1 minute 
// This timer will tick every 1 minute 
_timer.Interval += 6000; 
// Activate the timer 
_timer.Enabled = true; 
// When timer "tick" 
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed); 
0

Êtes-vous sûr que c'est la minuterie qui est le problème? Il est extrêmement inhabituel pour un service Windows d'accéder au système audio (comment l'éteindre?) Il peut être bloqué ou il peut nécessiter l'activation de "l'interaction avec le bureau". Cela dit, TomTom a raison, Forms Timers est sur le point d'être en mesure de Marshal à la thread UI, ce que vous n'avez pas, plutôt en utilisant une minuterie Threading.