- Windows Service System.Timers.Timer not firing
- 6 Answers 6
- Using Timers in a Windows Service
- Windows Service Recap
- What Is a Timer?
- Controlling a Timer
- Using a System.Timers.Timer Sample Code
- Using a System.Timers.Timer in a Windows Service
- TimedItem Sample Code
- Using Timers in a Windows Service
- Windows Service Sample Code
- Windows Service Installer Sample Code
- Possible Enhancements
- Future Columns
- About the Author
- Use of Timer in Windows Service
- 6 Answers 6
Windows Service System.Timers.Timer not firing
I have a Windows service written in C# which is meant to perform a task every few minutes. I’m using a System.Timers.Timer for this but it doesn’t ever appear to fire. I’ve looked at many different posts here on SO and elsewhere and I’m not seeing what is wrong with my code.
Here is my code, with non-timer related items removed for clarity.
I’m really scratching my head over this one. Can anybody spot what silly thing I’m getting wrong?
EDIT: By suggestion, I added IntervalTimer.Enabled = true; before IntervalTimer.Start(); in the service OnStart method. This doesn’t resolve the issue.
I’ve added file trace logging into the service to confirm some of the internals and I know for sure that the Timer.Enabled value is true by the time OnStart() is finished.
6 Answers 6
Here is my work-around.
After way too many hours searching for an answer to this, I discovered a wide variety of articles and blogs discussing timers in Windows services. I’ve seen a lot of opinions on this and they all fall into three categories and in descending order of frequency:
Don’t use System.Windows.Forms.Timer because it won’t work. (this only makes sense)
Don’t use System.Threading.Timer because it doesn’t work, use System.Timers.Timer instead.
Don’t use System.Timers.Timer because it doesn’t work, use System.Threading.Timer instead.
Based on this, I tried 2. This is also the approach that seems to be recommended by Microsoft since they say that System.Timers.Timer is suited to «Server applications».
What I’ve found is that System.Timers.Timer just doesn’t work in my Windows Service application. Therefore I’ve switched over to System.Threading.Timer . It’s a nuisance since it requires some refactoring to make it work.
This is approximately what my working code looks like now.
I hate the «Doctor, doctor, it hurts when I do this. » solution, but that’s what I had to resort to. One more opinion on the pile for the next guy with this problem.
You forget to enable timer by setting:
Apparently, System.Timers.Timer hides any exceptions, swallows them quietly, and then chokes. Of course, you can handle these in your method that you’ve added as a handler to your timer, but if the exception is thrown immediately on entrance (before the first line of code is executed, which can happen if your method declares a variable that uses an object in a strong-named DLL of which you have the wrong version, for instance), you are never going to see that exception.
And you are going to join us all in tearing your hair out.
Or you could do this:
- create a wrapper method that (in a try-catch loop) calls the method you would like to have executed. If this method is dying on you, the wrapped method can do the exception handling, without killing the timer, because if you do not stop the timer, it will never notice something went wrong.
(I did end up stopping the timer, because if it fails, trying again makes no sense for this particular application. )
Hope this helps those who landed here from Google (as did I).
I also had to switch to System.Threading.Timer. To make re-factoring easier and others live easy, I created a separate class, containing an instance of System.Threading.Timer and has almost the same methods as System.Timers.Timer, so that calling code requires minimal changes:
I hope this will help!
To add to what «user1820848» wrote, because that was my problem as well, if your System.timers.timer elapsed event doesn’t seem to be firing, put everything in the event handler in a try/catch block, and look for any problem there. I tried all of the recommended methods to deal with this problem (or thought I had), including switching from system.timers.timer to system.threading.timer, and that didn’t work either.
I think the problem is compounded because many of us are moving our applications from our workstation, where we can attach to the running service and verify that it works, to a server where we don’t have any debugging support. So you’re stuck with event log messages or tracelistener messages, and it’s completely odd that the event doesn’t fire.
I had a situation where I have three running services on this server, running essentially the same timer code. I even went line by line with another running service’s code to make sure I was doing the system.timers.timer handling the same. But the other service works fine, and this one didn’t seem to be firing the event at all.
The problem, as it turned out, was that in my initial dim statements I was firing up a class that was trying to connect to Oracle. That call was failing, but it was actually failing because the Oracle client version on my workstation and server was slightly different. It happened when the CLR was resolving the references, so it wasn’t caught in my underlying class try/catch blocks. If I were debugging, the debugger would have flagged the error. Running on the server, the CLR had no way to tell me about the problem. So my service just sat there on an untrapped error.
Putting everything in a try/catch immediately pointed out the problem. Put your try before any declarations in that subroutine. If you’re failing on a very early statement, that’s how you’ll catch it.
[Sorry for the separate answer, but you have to provide answers to get enough reputation to even comment on someone else’s answer. ]
[Edit: another thing to try is take your code out of the timer event, put it into another sub/function, call that from your startup code, and also put the function call in your timer event. Weeks later, back at my workstation, trying to run the same code, and I have that sinking feeling that my timer event isn’t getting called, and I’ve been here before. Indeed! But putting everything in a try/catch isn’t working either. Moved it to a function call and Bam, there’s my exception — Oracle again. But it wasn’t coming up even with every single line inside a try/catch, until I moved the code out of the timer event and tried again.]
Using Timers in a Windows Service
Welcome to the next installment of the .NET Nuts & Bolts column. In one of the prior columns, «Creating a Windows Service in .NET,» we looked at the basics of creating a Windows Service. As a result of that article, I received a number of requests about how to create a service that takes an action on a scheduled interval. In this column, we’ll get more in depth with Windows Services and explore how to use timers within them. It will involve using classes in the System.ServiceProcess.ServiceBase and System.Timers namespaces, among others.
Windows Service Recap
A Windows Service is a long-running application without a user interface or any visual output. They are ideal for server environments where an application needs to continue to run regardless of whether a user is logged into the console or not. Microsoft server products, such as SQL Server and Exchange, are examples of Windows Service applications. For more basic information on Windows Services, refer to the prior .NET Nuts & Bolts column titled «Creating a Windows Service in .NET.»
What Is a Timer?
A timer is an object that can be used in your applications to cause an event to occur on a specified interval. There are three timer controls available within the Microsoft .NET Framework. Each one has it specific nuances. The three types of timers are as follows:
- System.Windows.Forms.Timer—is designed for use in a single threaded Windows Forms based application. This is the same timer design as what has been available since early versions of Visual Basic. A common mistake is attempting to use this timer in a Windows Service application.
- System.Timers.Timer—is an updated version of the Windows Forms timer that has been optimized to run in a server environment where a user interface does not exist. This timer is ideal for use in Windows Services.
- System.Threading.Timer—is designed for use with ThreadPools. It uses callback methods rather than events and therefore does not rely on the operating system to support timers. We won’t cover this timer as a part of this article.
Controlling a Timer
Each of the timers exposes some basic properties and methods that allow you to control its behavior. The Windows.Forms.Timer and Timers.Timer classes expose the same items:
- Enabled—property indicating whether or not the timer is enabled and should be raising the event.
- Interval—property allowing you to set the number of milliseconds between events.
- Start—method allowing you to start the timer.
- Stop—method allowing you to stop the timer.
The System.Threading.Timer object has different properties and methods for controlling its behavior. We’re not going to cover the use of this timer here, so we’ll skip the particulars.
Using a System.Timers.Timer Sample Code
The following sample code briefly demonstrates the programmatic setup of a timer in the System.Timers namespace. This example uses a Windows console application for simplicity in being able to see the outcome without requiring a lot of setup.
Using a System.Timers.Timer in a Windows Service
Now that we have seen a simple example of using a timer, we’ll get more complex and apply them to a Windows Service. The example in the prior column showed the creation and use of a single timer. This time around, we’ll spin up a number of threads and execute multiple timers. This will give us the opportunity to show how to set configurations in threads as well. The first thing we’ll need to do is create our item that will run as a thread. Then, we’ll create the Windows Service to create the threads. Finally, we’ll add an installer to handle the installation of the Windows Service.
TimedItem Sample Code
The following sample code contains an object with a single timer. It simply starts and stops the timer and responds to the timer’s event when appropriate. Because parameters cannot be passed to threads, we create a class like this and set the properties equal to the values we would want to pass as parameters to the method running as a thread. Each time the event fires for the item, an entry will be written to the Application log.
Using Timers in a Windows Service
Windows Service Sample Code
Now, we’ll create our service. The service will create a number of threads and execute the StartTimer method of the TimerItem on each thread. We’ll add an event log instance to record the start of the service and the timer events.
Windows Service Installer Sample Code
Now, we include the installer to control the installation of the service. If you have any problems getting this to install using the InstallUtil.exe, make sure you are using the InstallUtil.exe for the appropriate version of the .NET Framework you are using. If you have the 1.0 and 1.1 framework installed, there is a chance the InstallUtil.exe will point to the wrong version of the framework; this will result in an error when you try to install your 1.1-based Windows Service.
Possible Enhancements
Now you have seen a few ways in which timers can be used in a Windows Service application. Hopefully, those of you who contacted me with questions about how to use a timer in a service application will find this helpful. A few enhancements you can consider to make this more useful for yourself are as follows:
- Add a configuration file to the application and include the number of threads to create as a configurable item.
- Change the polling interval to be randomly generated for each thread. This will ensure that each thread is not taking action at the same time.
- Create an event log dedicated to the application. This will prevent the Application log from becoming overly cluttered with entries as you execute the application.
Future Columns
The topic of the next column is yet to be determined. If you have something in particular that you would like to see explained here, you could reach me at mstrawmyer@crowechizek.com.
About the Author
Mark Strawmyer, MCSD, MCSE, MCDBA is a Senior Architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in the architecture, design, and development of Microsoft-based solutions. Mark was honored to be named a Microsoft MVP for application development with C#. You can reach Mark at mstrawmyer@crowechizek.com.
This article was originally published on April 5th, 2004
Use of Timer in Windows Service
I have a windows service where in I want to create a file every 10 seconds.
I got many reviews that Timer in Windows service would be the best option.
How can I achieve this?
6 Answers 6
Firstly, pick the right kind of timer. You want either System.Timers.Timer or System.Threading.Timer — don’t use one associated with a UI framework (e.g. System.Windows.Forms.Timer or DispatcherTimer ).
Timers are generally simple
- set the tick interval
- Add a handler to the Elapsed event (or pass it a callback on construction),
- Start the timer if necessary (different classes work differently)
and all will be well.
I have a bit more information on this page, although I haven’t updated that for a long time.
I would not recommend System.Timers.Timer since it silently eats unhandled exceptions and therefore hides errors that you should fix. imho better that your code blows up in your face if you do not handle exceptions properly.
As for System.Threading.Timer I tend to use the Change method to start/stop the timer in a pattern like this:
This is how you do it simply
The Code above is the whole service with the timer. I realize this is an old post but it took me hours to figure this out. Hopefully it helps someone out there.
This should just be a case of firing up a System.Timers.Timer with the right Interval (and AutoReset set to true), and handling Elapsed (but watch out; the callback is not on any particular thread).
The Timer component is a server-based timer, which allows you to specify a recurring interval at which the Elapsed event is raised in your application. You can then handle this event to provide regular processing. For example, suppose you have a critical server that must be kept running 24 hours a day, 7 days a week. You could create a service that uses a Timer to periodically check the server and ensure that the system is up and running. If the system is not responding, the service could attempt to restart the server or notify an administrator.
The server-based Timer is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event, resulting in more accuracy than Windows timers in raising the event on time.