|
-
Nov 11th, 2015, 05:58 AM
#1
Thread Starter
Lively Member
[RESOLVED] Building a Windows Service with a Timer event
Good morning
A few months ago I wrote an application which sits on one of our servers and is triggered at 5-minute intervals by Windows Task Scheduler. The application interrogates a SQL database which has been designed to automatically generate outgoing emails, and when it's triggered it queries a particular table to get the details of all currently-outstanding emails. For various reasons, I want to do away with this approach and instead build a Windows Service which will be triggered to run every 2 seconds, but I've run into a little problem.
For the moment, I'm starting out with a nice simple service which does nothing more than write to a log file when it starts and stops. It is then supposed to write to a second file each time the timer_tick event is fired but isn't doing that. When I attach the VS2010 debugger to the running process, it appears that the timer_tick event is never being fired.
This is the code that's contained in the OnStart event:
Code:
Timer1.Interval = 2000
Timer1.Enabled = True
Timer1.Start()
' Add code here to start your service. This method should set things
' in motion so your service can do its work.
Dim fs As FileStream = New FileStream("C:\Temp\arvatoEmailSenderService_vb.txt", FileMode.OpenOrCreate, FileAccess.Write)
Dim m_StreamWriter As StreamWriter = New StreamWriter(fs)
With m_StreamWriter
.BaseStream.Seek(0, SeekOrigin.End)
If Timer1.Enabled Then
.WriteLine(DateTime.Now.ToShortDateString + " " + DateTime.Now.ToLongTimeString + " : arvatoEmailSenderService: Service Started. Timer is enabled and will ""tick"" every " & Me.Timer1.Interval & " milliseconds.")
Else
.WriteLine(DateTime.Now.ToShortDateString + " " + DateTime.Now.ToLongTimeString + " : arvatoEmailSenderService: Service Started. Timer would ""tick"" every " & Me.Timer1.Interval & " milliseconds.")
End If
.Flush()
.Close()
End With
This is the code contained in the OnStop event:
Code:
If Timer1.Enabled = True Then
Dim fs As FileStream = New FileStream("C:\Temp\arvatoEmailSenderService_vb.txt", FileMode.OpenOrCreate, FileAccess.Write)
Dim m_StreamWriter As StreamWriter = New StreamWriter(fs)
With m_StreamWriter
.BaseStream.Seek(0, SeekOrigin.End)
.WriteLine(DateTime.Now.ToShortDateString + " " + DateTime.Now.ToLongTimeString + " : arvatoEmailSenderService: Service Stopped")
.Flush()
.Close()
End With
End If
This is the code that's contained in the timer's Tick event:
Code:
' Add code here to perform any tear-down necessary to stop your service.
Dim fs As FileStream = New FileStream("C:\Temp\arvatoEmailSenderService_vb2.txt", FileMode.OpenOrCreate, FileAccess.Write)
Dim m_StreamWriter As StreamWriter = New StreamWriter(fs)
With m_StreamWriter
.BaseStream.Seek(0, SeekOrigin.End)
.WriteLine(DateTime.Now.ToShortDateString + " " + DateTime.Now.ToLongTimeString + " : arvatoEmailSenderService: Service Ran")
.Flush()
.Close()
End With
As you can see, there's nothing particularly fancy going on in the Tick event. As a test, I've also tried that same code in a Timer on a regular Windows form project and it works exactly as it should.
I really hope someone can help - I'm in a team of 5 developers and none of us can figure out why this seemingly simple piece of code isn't doing what it should.
TIA
-
Nov 11th, 2015, 07:17 AM
#2
Re: Building a Windows Service with a Timer event
If you have a Tick event then you're using the wrong Timer. That's a Windows Forms Timer. You should be using a System.Timers.Timer, which has an Elapsed event.
-
Nov 11th, 2015, 08:14 AM
#3
Re: Building a Windows Service with a Timer event
The "why" to that is:
System.Windows.Forms.Timer is technically a UI type. It does some special things that only UI types do, those things are required so the timer can always raise its event on the UI thread.
You aren't allowed to interact with the Desktop in services. Reading around reveals that trying to do so redirects the UI to "Session 0", which seems like saying, "The UI gets displayed to a user that no one is allowed to log in as." Since the S.W.F.Timer is technically UI, it doesn't work.
The other timer classes in .NET aren't designed to make the guarantees that S.W.F.Timer makes, so they don't count as UI classes and will work in a service.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Nov 11th, 2015, 08:20 AM
#4
Thread Starter
Lively Member
Re: Building a Windows Service with a Timer event
JMC, you're an absolute life-saver.
In my defence as a newbie to the world of service-writing, I dragged the Timer control from the Toolbox. Whilst I admit that the fact it was in the "All Windows Forms" group on the toolbox should perhaps have been a subtle hint, I chose it because it's the only Timer control available that I can see.
Either way, I swapped to the new Timer control and it works flawlessly, so thank you very much
-
Nov 11th, 2015, 05:43 PM
#5
Re: Building a Windows Service with a Timer event
 Originally Posted by ianbhenderson73
JMC, you're an absolute life-saver.
In my defence as a newbie to the world of service-writing, I dragged the Timer control from the Toolbox. Whilst I admit that the fact it was in the "All Windows Forms" group on the toolbox should perhaps have been a subtle hint, I chose it because it's the only Timer control available that I can see.
Either way, I swapped to the new Timer control and it works flawlessly, so thank you very much 
The Timers.Timer used to be in the Toolbox by default in older versions of VS. It probably wasn't used much from there and may have caused confusion, so that's probably why it was removed. You can add it in yourself or just use it in code.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|