title: Multi threaded task not utilizing CPU?
body: <p>I have a method in C# that I want to run from multiple threads for lets say 20 times in a console app, on a 4 core machine. The problem I am facing is that the results are not what I expect them to be. When I run the method 25 times sequentially, the time taken is X and I can see in perfmon that max CPU is 100% (it tells me that it is using 1 core). Running the same method using multiple threads, I expect the execution time to be X/4 and also I expect the max CPU usage in perfmon to be 400% (since it is a 4 core machine). However, I can only see that the execution time is X/2 and the max CPU usage has never been more than 275%. I have tried various things such as creating my own threads, using threasdpool etc. and nothing seems to work. Can somebody please explain/help me understand it better?</p>
  
  <p>Other interesting thing is that if I replace my method with a dummy task using <code>Thread.SpinWait(x)</code> the execution time is X/4 and I can see max CPU going to 400%. This tells me that something is wrong in my method and I don't understand what it is. I have no locks/sleep anywhere in my method. Following is the code I use to execute:</p>
  
  <pre><code>public static void DoWorkParallel()
  {
      var s = new List&lt;string&gt; { "a", "b", "c", "d", "e", etc. };
      s.ParallelForEach2(x =&gt;
                         {
                             MyTask(x);
                         });
  }
  
  public static void DoWorkSequential()
  {
      var s = new List&lt;string&gt; { "a", "b", "c", "d", "e", etc. };
      foreach (var ss in s)
      {
          MyTask(x);
      }       
  }
  
  public static void ParallelForEach&lt;T&gt;(this IEnumerable&lt;T&gt; collection, Action&lt;T&gt; action)
  {
      var results = collection.Skip(1).Select(item =&gt; new 
      {
          action,
          res = action.BeginInvoke(item, null, null)
      }).ToArray();
  
      action(collection.First()); /* let the mainthread do a job too*/
  
      foreach (var r in results)
      {
          r.action.EndInvoke(r.res); /*then wait the rest of time */
      }
  }
  </code></pre>