title: Using a timer in a Windows service - elapsed event handler keeps firing even when the timer is disabled
body: <p>I've read a lot of the posts related to Windows services and the use of timers, but I haven't found any reason why my event handler is still being triggered.  Could anyone point me in the right direction?  I want to know <em>why</em> this is happening so I understand how to avoid this in the future.</p>
  
  <p>Edit: The onError event handler is never invoked (or I would have seen the event in the event log).</p>
  
  <p><strong>Timer:</strong> System.Timers.Timer<br/>
  <strong>ServiceBase:</strong> System.ServiceProcess.ServiceBase</p>
  
  <hr>
  
  <p>Here is the abstract class:</p>
  
  <pre><code>public abstract class ABCService : ServiceBase
  {
      // Members
      protected Timer             invocationTimer;
      protected Timer             wellnessTimer;
      protected FileSystemWatcher fsw;
  
  
      // Constructors
      protected ABCService()
      {
          invocationTimer = new Timer();
          wellnessTimer   = new Timer();
          fsw             = null;
  
          invocationTimer.AutoReset = false;
          invocationTimer.Interval  = 30000; // 30 seconds
          invocationTimer.Elapsed  += new ElapsedEventHandler(invocationTimer_Elapsed);
  
          wellnessTimer.AutoReset   = false;
          wellnessTimer.Elapsed    += new ElapsedEventHandler(wellnessTimer_Elapsed);
      }
  
  
      // Methods
      protected void invocationTimer_Elapsed(object o, ElapsedEventArgs args)
      {
          try
          {
              // log to event log
  
              invocationTimer.Stop();
  
              if ((new FileInfo(fsw.Path + "\\" + fsw.Filter)).Exists)
              {
                  onCreated(this, new FileSystemEventArgs(WatcherChangeTypes.Created, fsw.Path, fsw.Filter));
              }
          }
          catch (Exception x)
          {
              onError(this, new ErrorEventArgs(x));
          }
      }
  
      protected void wellnessTimer_Elapsed(object o, ElapsedEventArgs args)
      {
          try
          {
              // log to event log
  
              wellnessTimer.Stop();
              wellnessTimer.Interval = 60000; // ms
  
              if (fsw != null)
              {
                  fsw.Dispose();
              }
  
              fsw = new FileSystemWatcher(ConfigurationManager.AppSettings["pathKey"], ConfigurationManager.AppSettings["filterKey"]);
  
              invocationTimer.Start();
          }
          catch (Exception x)
          {
              onError(this, new ErrorEventArgs(x));
          }
      }
  
      protected abstract void onCreated(object o, FileSystemEventArgs args);
  
      protected virtual void onError(object o, ErrorEventArgs args)
      {
          // log to event log
  
          wellnessTimer.Start();
      }
  
      protected override void OnStart(string[] args)
      {
          // log to event log
  
          wellnessTimer.Interval = 5000; // 5 seconds
          wellnessTimer.Start();
      }
  
      protected override void OnStop()
      {
          // log to event log
  
          wellnessTimer.Stop();
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Here is an instance class:</p>
  
  <pre><code>public partial class Service1 : ABCService
  {
      // Members
      private static object locket = new object();
      private static DateTime LAST_RUN_TIME = DateTime.Now.AddSeconds(-10);
  
  
      // Constructors
      public Service1()
      {
          InitializeComponent();
      }
  
  
      // Methods
      protected override void onCreated(object o, FileSystemEventArgs args)
      {
          lock (locket)
          {
              // log to event log
  
              if ((DateTime.Now - LAST_RUN_TIME).Seconds &gt;= 10)
              {
                  // do stuff
              }
              else
              {
                  // log to event log
  
                  invocationTimer.Stop();
                  invocationTimer.Start();
              }
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <p>Here is the autogenerated code for the partial class:</p>
  
  <pre><code>partial class Service1
  {
      /// &lt;summary&gt; 
      /// Required designer variable.
      /// &lt;/summary&gt;
      private System.ComponentModel.IContainer components = null;
  
      /// &lt;summary&gt;
      /// Clean up any resources being used.
      /// &lt;/summary&gt;
      /// &lt;param name="disposing"&gt;true if managed resources should be disposed; otherwise, false.&lt;/param&gt;
      protected override void Dispose(bool disposing)
      {
          if (disposing &amp;&amp; (components != null))
          {
              components.Dispose();
          }
          base.Dispose(disposing);
      }
  
      #region Component Designer generated code
  
      /// &lt;summary&gt; 
      /// Required method for Designer support - do not modify 
      /// the contents of this method with the code editor.
      /// &lt;/summary&gt;
      private void InitializeComponent()
      {
          // 
          // Service1
          // 
          this.ServiceName = "Service1";
  
      }
  
      #endregion
  }
  </code></pre>
  
  <hr>
  
  <p>So what exactly is happening?  I'm looking at my event log and I see that once every minute the wellnessTimer event handler is invoked.</p>
  
  <p>Here is what I <strong>think</strong> is happening, but I'm obviously wrong:</p>
  
  <pre><code>1. Service is started via MMC
  2. OnStart() method is invoked
  3. wellnessTimer interval is set to 5 seconds
  4. wellnessTimer start method is invoked
  5. wellnessTimer_Elapsed event handler is invoked
  6. wellnessTimer stop method is invoked
  7. wellnessTimer interval is set to 5 minutes
  8. invocationTimer start method is invoked
  9. 30 seconds later, the invocationTimer_Elapsed method is invoked
  10. invocationTimer stop method is invoked
  </code></pre>
  
  <p>At this point both timers should still exist for this instance, but should be disabled.  I debugged this via attach to process in Visual Studio 2010 and marked an ID for the object (sender) being passed into the event handlers.  It is the same object as the instance.  Also, both timers in the Locals window had their enabled property set to false.</p>
  
  <p>This makes me thing I'm using inheritance incorrectly, or something is going on with threading.  I'm not the best at either of those things, but if it is due to them please let me know so I can learn.</p>
  
  <p>Thanks to everyone in advance.</p>
  
  <hr>
  
  <p>Edit #2: Here is some trace data...</p>
  
  <p>'o' represents the object passed into the event handler</p>
  
  <pre><code>ABCService() method invoked &lt;--
  ABCService() method invoked --&gt;
  
  Service1() method invoked &lt;--
  Service1() method invoked --&gt;
  
  OnStart() method invoked &lt;--
  OnStart() method invoked --&gt;
  
  wellnessTimer_Elapsed() method invoked &lt;--
  ((System.Timers.Timer) o).Enabled  = False
  ((System.Timers.Timer) o).Interval = 5000
  this.wellnessTimer.Enabled  = False
  this.wellnessTimer.Interval = 5000
  wellnessTimer_Elapsed() method invoked --&gt;
  
  invocationTimer_Elapsed() method invoked &lt;--
  ((System.Timers.Timer) o).Enabled  = False
  ((System.Timers.Timer) o).Interval = 30000
  this.invocationTimer.Enabled  = False
  this.invocationTimer.Interval = 30000
  invocationTimer_Elapsed() method invoked --&gt;
  
  wellnessTimer_Elapsed() method invoked &lt;--
  ((System.Timers.Timer) o).Enabled  = False
  ((System.Timers.Timer) o).Interval = 60000
  this.wellnessTimer.Enabled  = False
  this.wellnessTimer.Interval = 60000
  wellnessTimer_Elapsed() method invoked --&gt;
  
  invocationTimer_Elapsed() method invoked &lt;--
  ((System.Timers.Timer) o).Enabled  = False
  ((System.Timers.Timer) o).Interval = 30000
  this.invocationTimer.Enabled  = False
  this.invocationTimer.Interval = 30000
  invocationTimer_Elapsed() method invoked --&gt;
  </code></pre>