Reputation: 16565
I have a window service which plays a sound file at a specified time, so to do that I have taken Timer but it's Tick event is never fired, same is working in WinForm application.
Below is the code snippet of my 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;
}
}
}
To make sure that I have done everything properly, here is my InitializeComponent method
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";
}
Please anyone have a look and guide me...problem is the tick event is never fired..
Upvotes: 4
Views: 9066
Reputation: 4842
Are you sure it's the timer that's the issue? It's extremely unusual for a windows service to access the sound system, (How would you turn it off?) it may be blocked or it may require "interaction with desktop" enabled.
Having said that, TomTom is right, Forms Timers are about being able to Marshal to the UI thread, which you don't have, rather using a Threading timer.
Upvotes: 0
Reputation: 1616
I think System.Timers.Timer is a better choice :
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);
Upvotes: 1
Reputation: 62157
Dont use a System.Windows.FOrms.Timer, use a System.Threading.Timer.
A service is not a form.
Upvotes: 0
Reputation: 755321
Try to use the System.Timers.Timer
instead.
this.alarmTimer = new System.Timers.Timer();
The System.Windows.Forms.Timer
- as it names implies - works in Forms applications, but not in something like a NT Service.
Upvotes: 11