title: Why doesn't a foreach loop work in certain cases?
body: <p>I was using a foreach loop to go through a list of data to process (removing said data once processed--this was inside a lock). This method caused an ArgumentException now and then.</p>
  
  <p>Catching it would have been expensive so I tried tracking down the issue but I couldn't figure it out.</p>
  
  <p>I have since switched to a for loop and the problem seems to have went away. Can someone explain what happened? Even with the exception message I don't quite understand what took place behind the scenes.</p>
  
  <p>Why is the for loop apparently working? Did I set up the foreach loop wrong or what?</p>
  
  <p>This is pretty much how my loops were set up:</p>
  
  <pre><code>foreach (string data in new List&lt;string&gt;(Foo.Requests))
  {
      // Process the data.
  
      lock (Foo.Requests)
      {
          Foo.Requests.Remove(data);
      }
  }
  </code></pre>
  
  <p>and</p>
  
  <pre><code>for (int i = 0; i &lt; Foo.Requests.Count; i++)
  {
      string data = Foo.Requests[i];
  
      // Process the data.
  
      lock (Foo.Requests)
      {
          Foo.Requests.Remove(data);
      }
  }
  </code></pre>
  
  <p>EDIT: The for* loop is in a while setup like so:</p>
  
  <pre><code>while (running)
  {
      // [...]
  }
  </code></pre>
  
  <p>EDIT: Added more information about the exception as requested.</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 (System.Array sourceArray, Int32 sourceIndex, System.Array destinationArray, Int32 destinationIndex, Int32 length) [0x00000] 
    at System.Collections.Generic.List`1[System.String].CopyTo (System.String[] array, Int32 arrayIndex) [0x00000] 
    at System.Collections.Generic.List`1[System.String].AddCollection (ICollection`1 collection) [0x00000] 
    at System.Collections.Generic.List`1[System.String]..ctor (IEnumerable`1 collection) [0x00000]
  </code></pre>
  
  <p>EDIT: The reason for the locking is that there is another thread adding data. Also, eventually, more than one thread will be processing data (so if the entire setup is wrong, please advise).</p>
  
  <p>EDIT: It was hard to pick a good answer.</p>
  
  <p>I found Eric Lippert's comment deserving but he didn't really answer (up-voted his comment anyhow).</p>
  
  <p>Pavel Minaev, Joel Coehoorn and Thorarin all gave answers I liked and up-voted. Thorarin also took an extra 20 minutes to write some helpful code.</p>
  
  <p>I which I could accept all 3 and have it split the reputation but alas.</p>
  
  <p>Pavel Minaev is the next deserving so he gets the credit.</p>
  
  <p>Thanks for the help good people. :)</p>