title: System.Timers.Timer Elapsed taking 10 times longer to execute than a Button_click
body: <p>I have a fairly process intensive method that takes a given collection, copies the items(the Item class has its Copy() method properly defined), populates the item with data and returns the populated collection to the class's collection property</p>
  
  <pre><code>//populate Collection containing 40 items
  MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
  </code></pre>
  
  <p>This method is called in two ways: upon request and via a System.Timers.Timer object's 'Elapsed' event.</p>
  
  <p>Now 40 items in the collection take almost no time at all. Whether being populated 'ad hoc' by say a button_click or populated by the Timer object.</p>
  
  <p>Now when I increase the size of the collection (another MyClass object that has 1000 items), the process predictably takes longer, but around 6sec in total.
  That's fine, no problems there. Being called upon initialization (form_load) or being called ad hoc (button_click) it stays around 6sec.</p>
  
  <pre><code>//populate Collection containing 1000 items
  MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems );
  </code></pre>
  
  <p>But, the SAME METHOD (as in the exact line of code) is being called by the System.Timers.Timer object.  And that Elapsed takes around 60 seconds (other runs unclide 56sec, 1min 2Sec, 1min 10 sec... you get the idea).
  Ten times as long for the same process!</p>
  
  <p>I know the System.Timers.Timer object is executed in the Thread-pool. Could this be the reason? Is the thread-pool given lower priority or is the whole queuing thing taking up the time?</p>
  
  <p>In short, what would be a better approach to this?  Using the System.Windows.Forms.Timer to execute in the same UI thread?</p>
  
  <p>Thanks!</p>
  
  <p>Ok, some additional info:</p>
  
  <p>The timer operation is occurring within a DLL being called by the UI. The main 'handler' class itself has a collection of timer objects all subscribing to the same event handler.
  The handler class' initialization works kinda like this:</p>
  
  <pre><code>UpdateIntervalTimer tmr = new UpdateIntervalTimer(indexPosition);
  tmr.Interval = MyClass.UpdateInterval * 60000; //Time in minutes
  tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed);
  this.listIntervalTimers.Add(tmr);
  </code></pre>
  
  <p>I've actually inherited the Timer class to give it an 'index' property (The eventArgs as well). That way within one event handler (tmr_Elapsed) i can identify which MyClass object the timer is for and take action.</p>
  
  <p>The handler class is already running in a thread of its own and fires a custom event to give insight to its operations.
  The event is handled in the UI (cross-threading access of UI controls and whatnot) and displayed with the time recievedthe event is handled.  This is true for both 'initialization' and 'ad hoc' calls (there is no problem in those cases).</p>
  
  <p>The actual Elapsed event looks as follows:</p>
  
  <pre><code>private void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
              UpdateIntervalTimer tmr;
              tmr = (UpdateIntervalTimer)sender;
  
              MyClass c = listOfClasses[tmr.IndexPosition];
  
              observerEventArguments = new MyHandlerEventArgs("Timer is updating data for " + MyClass.ID);
              MessagePosted(this, observerEventArguments);
  
              try
              {
                  //preparation related code
  
  
                  MyClass.CollectionOfItems = GetPopulatedCollection(MyClass.CollectionOfItems);
  
  
                  observerEventArguments = new ProfileObserverEventArgs(MyClass.ID + ": Data successfully updated");
                  MessagePosted(this, observerEventArguments);
              }
              catch (Exception exUpdateData)
              {
                  observerEventArguments = new MyHandlerEventArgs("There was an error updating the data for '" + MyClass.ID + "': " + exUpdateData.Message);
                  MessagePosted(this, observerEventArguments);
              }
          }
  </code></pre>