title: Uncatchable exception in DataGridView when deleting rows in datatable
body: <p>I have a data table in which rows are added based on data available on the internet. Each time I add a row, I also put a timestamp on the row.  This has been working for a number of years, with hundreds of users with no errors occurring.  I now wish to delete rows from the data table based on the age of the data.  I have a timer that fires every user defined interval and then I search for all rows that are older and I delete them.  The problem is, that I am receiving various errors that seem to change and even though I have try catch statements on all methods, the errors are not caught.  The error is caught only on an error catch on the whole application in program.cs
  The errors are "Exit error: Object reference not set to an instance of an object.   at System.Windows.Forms.DataGridViewCell.PaintWork,
  or Exit error: Index was out of range. Must be non-negative and less than the size of the collection.
  Parameter name: index   at System.Collections.ArrayList.get_Item(Int32 index)</p>
  
  <p>or 
  Exit error: Object reference not set to an instance of an object.   at System.Windows.Forms.DataGridViewTextBoxCell.PaintPrivate</p>
  
  <p>but there is no useful information in the rest of the errors.
  Here is the code:</p>
  
  <pre><code>    public void ageTimer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
      {
          try
          {
              spotAge = Convert.ToDouble(Properties.Settings.Default.SpotAge);
  
              //Select all rows in datatable where the age is older than spotAge and delete them.
              //date is stored in dt as 20:12:2017: 21:49:02 derived from DateTime.UtcNow.ToString("dd:MM:yyyy: HH:mm:ss")
  
              //spotTime is the time from the table
  
              DateTime spotTime;
              dt.AcceptChanges();
              var rowCount = dt.Rows.Count;
  
              for (int i = rowCount -1; i &gt;= 0; i--)
              {
                  DataRow dr = dt.Rows[i];
  
                  spotTime = DateTime.ParseExact(Convert.ToString(dr["date"]), "dd:MM:yyyy: HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
  
                  if (spotTime.AddMinutes(spotAge) &lt;= DateTime.UtcNow)
                  {
                      dr.Delete();
  
                  }
              }
  
              dt.AcceptChanges();
  
              dataGridView1.Update();
              dataGridView1.Refresh();
              dataGridView1.FirstDisplayedScrollingRowIndex = 0;
          }
  
          catch (Exception x)
          {
  
          }
      }
  </code></pre>
  
  <p>Now the interesting thing is that on my system this will not crash at all ever.  However, if I run visual studio in debug mode it will. It will also crash on a small number of users as well.  But not everyone.</p>
  
  <p>I tried the same code except I always will delete only one row and it works perfectly fine.  I tried deleting every row except for the first, the first two and it still crashes.</p>
  
  <p>Based on the comment below which pointed out that the timer was running on a separate thread, I added the following:</p>
  
  <pre><code>    public void ageTimer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
      {
          DeleteRows("");
      }
  </code></pre>
  
  <p>and the above code now now has the following:</p>
  
  <pre><code>private void DeleteRows(string details)
  {
    if (InvokeRequired)
    {
       this.Invoke(new Action&lt;string&gt;(DeleteRows), new object[] { details});
       return;
    }
  </code></pre>
  
  <p>and the rest of the code is as above.  This solves the issue completely.
  Many thanks!</p>