title: Simple LOCK and ThreadPoolQuestion for WP7 (C#)
body: <p><br>
  funny, I was going to test tombstoning and concurrency, and during my simple setup, I thought what the heck, is it really worth the trouble. But now, after 45 minutes of setting up some stupid test classes, I ran into the first error I don't understand.</p>
  
  <p>Seems I need a little bit more practice in lists, locks and threads.
  Does anyone know why this throws an illegal operation exception (see attached code).</p>
  
  <p>For one who likes the F5 experience better, here is the complete solution (300kB)<br>
  <a href="http://www.filesavr.com/TXXXFVE40GTJK43" rel="nofollow">http://www.filesavr.com/TXXXFVE40GTJK43</a></p>
  
  <p>Do not open the views, they might crash your VS2010. And you need the WP7 tools, sorry, even though I am pretty sure this example would work (not work) on pure C# also.</p>
  
  <p><strong>[EDIT]</strong>
  I update the link, now it is working (with the old code)<br>
  And I found the first bug, thanks to the comment.</p>
  
  <p>This works:</p>
  
  <pre><code>    private void IncOneWithLock()
      {
          lock (CounterListOne)
          {
              IncListOne();
          }
      }
  
      private void IncListOne()
      {
          if (CounterListOne == null)
          {
              Log("CounterListOne == null");
              return;
          }
  
          var c = 0;
          var oldList = CounterListOne.ToList();
          foreach (var i in oldList)
          {
              CounterListOne[c++] = i + 1;
              Thread.Sleep(Next(80*DelayFactor, 150*DelayFactor));
          }
      }
  </code></pre>
  
  <p>Will keep testing tombstoning stuff and post possible questions in later thread. Changing list while iterating - hello newbie mistake :-)</p>
  
  <p><strong>[/EDIT]</strong></p>
  
  <p>For your conveniece, the expection occurs in this function, and its an invalid operation expection:</p>
  
  <pre><code> private void IncOneWithLock()
      {
          if (CounterListOne == null)
          {
              Log("CounterListOne == null");
              return;
          }
  
          lock (this)
          {
              var c = 0;
              foreach (var i in CounterListOne)
              {
                  CounterListOne[c++] = i + 1;
                  Thread.Sleep(Next(80 * DelayFactor, 150 * DelayFactor));
              }
          }
      }
  </code></pre>
  
  <p>Here is the full source of the test class:</p>
  
  <pre><code>public class CounterClass : TestBase
  {
      private DispatcherTimer _dT;
      public int CounterA { get; set; }
  
      public ObservableCollection&lt;int&gt; CounterListOne { get; set; }
      public List&lt;int&gt; CounterListTwo { get; set; }
      public List&lt;int&gt; CounterListThree { get; set; }
      private const int DelayFactor = 10;
  
  
      public CounterClass()
      {
          CounterListOne = new ObservableCollection&lt;int&gt;();
          CounterListTwo = new List&lt;int&gt;();
          CounterListThree = new List&lt;int&gt;();
  
          InitCounterLists();
          StartBackgroundLogger();
      }
  
      public void LogLists()
      {
          lock (this)
              //lock (CounterListTwo)
               //   lock (CounterListThree)
                  {
                      Log("====================================================");
                      Log("CounterListOne   " + String.Join("-", CounterListOne.Select(x =&gt; x.ToString()).ToArray()));
                      Log("CounterListTwo   " + String.Join("-", CounterListTwo.Select(x =&gt; x.ToString()).ToArray()));
                      Log("CounterListThree " + String.Join("-", CounterListThree.Select(x =&gt; x.ToString()).ToArray()));
                      Log("====================================================");
                  }
      }
  
      public void RunTests()
      {
          Log("MultiIncWithoutLocks");
          //MultiIncWithoutLocks();
  
          Log("MultiIncWithLocks");
          MultiIncWithLocks();
      }
  
      public void MultiIncWithoutLocks()
      {
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithoutLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithoutLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithoutLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithoutLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithoutLock());
      }
  
      public void MultiIncWithLocks()
      {
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithLock());
          ThreadPool.QueueUserWorkItem(x =&gt; IncOneWithLock());
      }
  
      private void IncOneWithoutLock()
      {
          var c = 0;
          foreach (var i in CounterListOne)
          {
              CounterListOne[c++] = i+1;
              Thread.Sleep(Next(80 * DelayFactor, 150 * DelayFactor));
          }
      }
  
      private void IncOneWithLock()
      {
          if (CounterListOne == null)
          {
              Log("CounterListOne == null");
              return;
          }
  
          lock (this)
          {
              var c = 0;
              foreach (var i in CounterListOne)
              {
                  CounterListOne[c++] = i + 1;
                  Thread.Sleep(Next(80 * DelayFactor, 150 * DelayFactor));
              }
          }
      }
  
      private void InitCounterLists()
      {
          InitCounterOne();
          InitCounterTwo();
          InitCounterThree();
      }
  
  
      private void InitCounterOne()
      {
          for (int i = 0; i &lt; Next(1, 5); i++)
          {
              CounterListOne.Add(0);
          }
      }
  
      private void InitCounterTwo()
      {
          for (int i = 0; i &lt; Next(1, 5); i++)
          {
              CounterListTwo.Add(0);
          }
      }
  
      private void InitCounterThree()
      {
          for (int i = 0; i &lt; Next(1, 5); i++)
          {
              CounterListThree.Add(0);
          }
      }
  
      private void StartBackgroundLogger()
      {
           _dT = new DispatcherTimer();
           _dT.Tick += (a,b) =&gt; LogLists();
          _dT.Interval = new TimeSpan(0,0,0,3);
          _dT.Start();
      }
  
  
  }
  </code></pre>