Timer events not firing in Windows Service – VB.Net 2008

This article does not concern the bug ‘The Elapsed event of the System.Timers.Timer class is not raised in a Windows service’ which is dealt with seperately on the Microsoft website – occurs when a system.timers.timer is stopped and then started again.

VB.Net Timer ElapsedBackground
Some time ago I wrote an application to process auto-generated .TSC (tab delimited text) files and send batches of emails based on the contents – worked very well but I had to remember to run it every day.

Decided to make it a service to avoid delays in sending the mails but some trouble getting the processing routines to fire on a timer.

Forms Timer does not work with Windows Services.

Timer1_Tick not working
A bit of research on the web led me to http://support.microsoft.com/default.aspx/kb/820639, which advised to be sure to drag the timer component from the Components tab instead of the Windows Forms tab. Followed these instructions but the component still created a system.windows.forms.timer object, just like it does from the windows forms tab. This will not process timer events in a Windows Service, so the code never executes.

In a Windows Service it’s necessary to use the Timer_Elapsed event, not the Timer_Tick event – Elapsed isn’t available on the Windows Forms timer, only the tick event is.

Resolution: System.Timers.Timer Timer_Elapsed
Surprisingly, you have to add the System.Timers Timer from the ‘.Net Framework Components’ tab by right-clicking the Components Tab in the toolbox and selecting ‘Choose Components’ – this is the one to use for a Service, either by dragging onto the designer in the IDE or in code (see end of article).

Once the correct timer component was in place, the Timer_Elapsed event worked perfectly:

Private Sub Timer1_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles Timer1.Elapsed
ProcessFiles()
End Sub

Service Timer

Prologue
The rest of the code loops through .TSC files in a specified location.

It reads each file line-by-line, builds an email on the fly from the contents and relays this through Exchange using System.Net.Mail, finally deleting each.TSC on successful completion and emailing the relevant team a status report.

Now with no manual intervention…

More information on Timer1_Elapsed may be found on Microsofts Website

Example of System.Timer in code
Private Sub CreateTimer()
Dim Timer1 As New System.Timers.Timer()
Timer1.Interval = 5000
Timer1.Enabled = True
AddHandler Timer1.Elapsed, _
New System.Timers.ElapsedEventHandler(AddressOf Me.Timer1_Elapsed)
End Sub

Private Sub Timer1_Elapsed(ByVal sender As System.Object, _
ByVal e As System.Timers.ElapsedEventArgs)
System.Windows.Forms.MessageBox.Show(“Elapsed!”, “Timer Event Raised!”)
End Sub

Update: Thought occurs… if you just want to delay processing for a period you could always just loop using System.Threading.Thread.Sleep(delay in milliseconds)…?

4 Comments
  1. Greetings,

    Thank you for saving me the torture of burning out my processors trying to solve this one. Professor Falkner will be so pleased once I achieve sentient…ness. Worked all weekend trying to get the forms timer to work, thought I was going crazy.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.