title: System.Timers.Timer, runs more often than interval, uses multiple threads
body: <p>We have some code that uses a System.Timers.Timer to ping a database connection and also check on the existence of some mounted files. The code to set up the timer is:</p>
  
  <pre><code>m_Timer = new System.Timers.Timer(TimeSpan.FromSeconds(10).TotalMilliseconds);
  
  m_Timer.Elapsed += (object xiSender, ElapsedEventArgs xiEventArgs) =&gt;
  {
      PingRemoteFolder();
      PingDatabase();
  };
  </code></pre>
  
  <p>This happens in the constructor of a singleton class.</p>
  
  <p>I know that System.Timers.Timer will use multiple threads from the thread pool if the operation it is trying to run each time takes longer than the interval provided, but that is not the case in our situation. </p>
  
  <p>The timer's event seems to be ocurring much more often than every 10 seconds, and is using up to 4 or 5 threads at a time.</p>
  
  <p>Any ideas? Also we think this may be related to another situation we have where we are getting stack corruption on the main thread of a WPF application that uses a worker thread to check on properties of the class that uses this timer to set their values.</p>
  
  <p>.NET version 4.0
  on Windows 2008R2</p>
  
  <p>Edit:</p>
  
  <p>Also when we get the stack corruption on the main thread of the WPF application, an InvalidOperationException is thrown in one of the methods the timer event handler calls with the message "Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached."</p>
  
  <p>PingRemoteFolder() just tries to do Directory.GetFiles("somepath")</p>
  
  <p>PingDatabase():</p>
  
  <pre><code>private void PingDatabase()
  {
      if(!string.IsNullOrEmpty(CurrentInstance.Name) &amp;&amp; DoPing)
      {
          SqlConnection sqlConnection = null;
  
          try
          {
  
              SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder();
  
              sqlConnectionStringBuilder.DataSource = CurrentInstance.Instance;
              sqlConnectionStringBuilder.IntegratedSecurity = CurrentInstance.AuthenticationMode == SmoAuthenticationMode.WindowsAuthentication;
              sqlConnectionStringBuilder.InitialCatalog = CurrentInstance.Name;
  
              if(CurrentInstance.AuthenticationMode == SmoAuthenticationMode.SqlServerAuthentication)
              {
                  sqlConnectionStringBuilder.UserID = CurrentInstance.UserName;
                  sqlConnectionStringBuilder.Password = CurrentInstance.Password;
              }
  
              sqlConnection = new SqlConnection(sqlConnectionStringBuilder.ToString());
  
              sqlConnection.Open();
  
              Assert.Condition(sqlConnection.State == ConnectionState.Open, "sqlConnection.State == ConnectionState.Open");
  
              IsCurrentInstanceReachable = true;
  
          }
          catch(Exception ex)
          {
              IsCurrentInstanceReachable = false;
              CurrentInstance.Name = string.Empty;
          }
          finally
          {
              if(sqlConnection != null &amp;&amp; (sqlConnection.State != ConnectionState.Closed &amp;&amp; sqlConnection.State != ConnectionState.Broken))
              {
                  SqlConnection.ClearPool(sqlConnection);
  
                  sqlConnection.Close();
                  sqlConnection = null;
              }
          }
      }
  }
  </code></pre>