title: What could cause "Destination array was not long enough" during List.Add in a single thread?
body: <p>I have a List of objects that I'm adding to in nested foreach loops. the operation is synchronous (or maybe I don't understand lambdas as well as I think I do) and single-threaded and the list isn't unreasonably big. I'm at a total loss for what could be causing this exception.</p>
  
  <pre><code>public string PromotionSpecificationIdGuid { get; set; }
  public virtual List&lt;ElementInstance&gt; ElementInstances { get; set; }
  
  public void UpdateInstanceGraph(OfferingInstance parentData, OfferingInstance offeringContainer = null)
  {
      ElementInstances = new List&lt;ElementInstance&gt;();
  
      parentData.ActiveServices.ForEach(
          service =&gt; service.ActiveComponents.ForEach(
              component =&gt; component.Elements.ForEach(
                  element =&gt;
                  {
                      if (element.PromotionId == this.PromotionSpecificationIdGuid)
                      {
                          ElementInstances.Add(element);
                      }
                  })));
  }
  </code></pre>
  
  <p>Which results in:</p>
  
  <pre><code>System.ArgumentException: Destination array was not long enough. Check destIndex and length, and the array's lower bounds.
         at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
         at System.Collections.Generic.List`1.set_Capacity(Int32 value)
         at System.Collections.Generic.List`1.EnsureCapacity(Int32 min)
         at System.Collections.Generic.List`1.Add(T item)
  </code></pre>
  
  <p>Trying to cover this with some unit tests and hammer on it, but I'm hoping someone can help me out in the mean time.</p>
  
  <p>-EDIT-</p>
  
  <p>Thanks to Juan and Mark I've figured out how this could happen. In my application, this operation is single threaded itself, but it uses what is essentially a singleton and is invoked via ajax. Multiple callers can start their own thread, and when those invocations are close enough together we get this behavior. I've made a console app to illustrate the concept.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Threading;
  using System.Threading.Tasks;
  
  namespace listaccessmonster
  {
      public class Program
      {
          private static List&lt;Guid&gt; baseList = new List&lt;Guid&gt;();
          private static List&lt;Guid&gt; activeList;
          private static Random rand = new Random();
  
          public static void Main(string[] args)
          {
              for(int i = 0; i &lt; 1000000; i++)
              {
                  baseList.Add(Guid.NewGuid());
              }
  
              var task1 = UpdateList(); //represents ajax call 1
              var task2 = UpdateList(); //represents ajax call 2
  
              var result = Task.WhenAll(task1, task2);
  
              try
              {
                  result.Wait();
              }
              catch(Exception e)
              {
                  Console.WriteLine(e);
              }
  
              task1 = UpdateListFixed(); //represents ajax call 1
              task2 = UpdateListFixed(); //represents ajax call 2
  
              result = Task.WhenAll(task1, task2);
  
              try
              {
                  result.Wait();
              }
              catch (Exception e)
              {
                  Console.WriteLine(e);
              }
  
              Console.WriteLine("press Enter to exit");
              Console.ReadKey();
          }
  
          private static Task UpdateList()
          {
              return Task.Run(()=&gt; {
                  Thread.Sleep(rand.Next(5));
                  Console.WriteLine("Beginning UpdateList");
                  activeList = new List&lt;Guid&gt;();
                  baseList.ForEach(x =&gt; {
                      activeList.Add(x);
                  });
              });
          }
  
          private static Task UpdateListFixed()
          {
              return Task.Run(() =&gt; {
                  Thread.Sleep(rand.Next(5));
                  Console.WriteLine("Beginning UpdateListFixed");
                  var tempList = new List&lt;Guid&gt;();
                  baseList.ForEach(x =&gt; {
                      tempList.Add(x);
                  });
                  activeList = tempList;
              });
          }
      }
  }
  </code></pre>
  
  <p>The exception or a similar exception is thrown most of the time, but not every time. It's never thrown with the Fixed method.</p>