Solved

System.Timers.Timer doesn't work in a Service on Windows Server 2003 Standard

Posted on 2004-09-25
5
475 Views
Last Modified: 2010-04-15
I've written a simple service, added a System.Timers.TImer to it and a EventLog.
When the service starts, stops, and the timer triggers, I log an event message.

I'm running the code on WindowsXP for development and it works just fine.
When I run it on the deployment server, Windows 2003 Server Standard Edition, I get the start/stop event logs but no timer events. It's like the timer is not clocking ????

I've tried running the service as a System account and even using the Administrator login/password. Still no timer.

What Am I missing for Windows 2003 ?

Thanks
0
Comment
Question by:mridey
  • 3
  • 2
5 Comments
 

Author Comment

by:mridey
ID: 12150218
Here's the relevant code:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Configuration;

namespace EMailCollect
{
      public class EMailCollectService : System.ServiceProcess.ServiceBase
      {
            private System.Timers.Timer timerReader;

            private System.Diagnostics.EventLog eventLogReader;

            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;

            public EMailCollectService()
            {
                  // This call is required by the Windows.Forms Component Designer.
                  InitializeComponent();
            }

            // The main entry point for the process
            static void Main()
            {
                  System.ServiceProcess.ServiceBase[] ServicesToRun;
      
                  // More than one user Service may run within the same process. To add
                  // another service to this process, change the following line to
                  // create a second service object. For example,
                  //
                  //   ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
                  //
                  ServicesToRun = new System.ServiceProcess.ServiceBase[] { new EMailCollectService() };

                  System.ServiceProcess.ServiceBase.Run(ServicesToRun);
            }

            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  //
                  // EMailCollectService
                  //
                  this.ServiceName = "EMailCollect";
            }

            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            /// <summary>
            /// Set things in motion so your service can do its work.
            /// </summary>
            protected override void OnStart(string[] args)
            {
                  // Create Log Reader
                  this.eventLogReader = new System.Diagnostics.EventLog("Application",".","EmailCollect");

                  // Create Timers
                  try
                  {
                        timerReader = new System.Timers.Timer();
                        timerReader.Elapsed += new System.Timers.ElapsedEventHandler(this.timerReader_Elapsed);
                        timerReader.Interval = 1000;
                        timerReader.Start();

                        LogInfo("Timer started");
                  }
                  catch (Exception ex)
                  {
                        LogError("Source: " + ex.Source + "\n" + "Message:\n" + ex.Message + "Stack:\n" + ex.StackTrace);
                  }
            }
 
            /// <summary>
            /// Stop this service.
            /// </summary>
            protected override void OnStop()
            {
                  timerReader.Stop();
            }

            private void timerReader_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
            {
                  LogInfo("Tiner triggered");
            }

            private void LogError(string message)
            {
                  eventLogReader.WriteEntry(message,System.Diagnostics.EventLogEntryType.Error);
            }
            private void LogWarning(string message)
            {
                  eventLogReader.WriteEntry(message,System.Diagnostics.EventLogEntryType.Warning);
            }
            private void LogInfo(string message)
            {
                  eventLogReader.WriteEntry(message,System.Diagnostics.EventLogEntryType.Information);
            }
      }
}
0
 
LVL 8

Expert Comment

by:Razzie_
ID: 12150226
I don't know if there is a difference in Eventlogs XP - 2003 (although I doubt it).

Have you debugged it by doing a try - catch and write exception messages to a log file or something? I'm quite sure this would easily tell you what the problem is.
0
 

Author Comment

by:mridey
ID: 12150240
I know the event messages are getting there since I get the "Timer started" message. I just never get any "Timer triggered" messages.

Actually the original service was doing much more and when I realized once installed that nothing was working, I trimed the code until I narrowed it down to the Timer.

So now i'm trying to figure out why the Timer class fails to run in a Win2003 Service?
0
 
LVL 8

Accepted Solution

by:
Razzie_ earned 500 total points
ID: 12150265
mridey:

I looked it up and it appears that the System.Timers.Timer can have problems in Windows Services. Apparantly this is some kind of Threading problem. The following links describes the problem a bit more and has multiple links to other articles covering this:

http://geekswithblogs.net/gavin/archive/2004/09/01/10546.aspx

I (and many others) recommend you to use the System.Threading.Timer instead.

HTH,

Razzie
0
 

Author Comment

by:mridey
ID: 12150322
Ok, using System.Threading.Timer :)

starting the timer is now:

// Start Timer
timerReader = new Timer(new TimerCallback(timerReader_Elapsed),this, 1000, long.Parse(interval));

And the timer handler becomes:

private void timerReader_Elapsed(object sender)

And to stop the timer:

// stop the timer
if (timerReader != null)
timerReader.Change(Timeout.Infinite, Timeout.Infinite);
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This video discusses moving either the default database or any database to a new volume.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now