title: understanding Parallel.Invoke, creation and reusing of threads
body: <p>I am trying to understand how <code>Parallel.Invoke</code> creates and reuses threads.
  I ran the following example code (from MSDN, <a href="https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx" rel="noreferrer">https://msdn.microsoft.com/en-us/library/dd642243(v=vs.110).aspx</a>):</p>
  
  <pre><code>using System;
  using System.Threading;
  using System.Threading.Tasks;
  
  class ThreadLocalDemo
  {
          static void Main()
          {
              // Thread-Local variable that yields a name for a thread
              ThreadLocal&lt;string&gt; ThreadName = new ThreadLocal&lt;string&gt;(() =&gt;
              {
                  return "Thread" + Thread.CurrentThread.ManagedThreadId;
              });
  
              // Action that prints out ThreadName for the current thread
              Action action = () =&gt;
              {
                  // If ThreadName.IsValueCreated is true, it means that we are not the
                  // first action to run on this thread.
                  bool repeat = ThreadName.IsValueCreated;
  
                  Console.WriteLine("ThreadName = {0} {1}", ThreadName.Value, repeat ? "(repeat)" : "");
              };
  
              // Launch eight of them. On 4 cores or less, you should see some repeat ThreadNames
              Parallel.Invoke(action, action, action, action, action, action, action, action);
  
              // Dispose when you are done
              ThreadName.Dispose();
          }
  }
  </code></pre>
  
  <p>As I understand it, <code>Parallel.Invoke</code> tries to create 8 threads here - one for each action. So it creates the first thread, runs the first <code>action</code>, and by that gives a <code>ThreadName</code> to the thread. Then it creates the next thread (which gets a different <code>ThreadName</code>) and so on.</p>
  
  <p>If it cannot create a new thread, it will reuse one of the threads created before. In this case, the value of <code>repeat</code> will be <code>true</code> and we can see this in the console output.</p>
  
  <p>Is this correct until here?</p>
  
  <p>The second-last comment ("Launch eight of them. On 4 cores or less, you should see some repeat ThreadNames") implies that the threads created by <code>Invoke</code> correspond to the available cpu threads of the processor: on 4 cores we have 8 cpu threads, at least one is busy (running the operating system and stuff), so <code>Invoke</code> can only use 7 different threads, so we must get at least one <code>"repeat"</code>.</p>
  
  <p>Is my interpretation of this comment correct?</p>
  
  <p>I ran this code on my PC which has an Intel® Core™ i7-2860QM processor (i.e. 4 cores, 8 cpu threads). I expected to get at least one <code>"repeat"</code>, but I didn't. When I changed the <code>Invoke</code> to take 10 instead of 8 actions, I got this output:</p>
  
  <pre><code>ThreadName = Thread6
  ThreadName = Thread8
  ThreadName = Thread6 (repeat)
  ThreadName = Thread5
  ThreadName = Thread3
  ThreadName = Thread1
  ThreadName = Thread10
  ThreadName = Thread7
  ThreadName = Thread4
  ThreadName = Thread9
  </code></pre>
  
  <p>So I have at least 9 different threads in the console application. This contradicts the fact that my processor only has 8 threads.</p>
  
  <p>So I guess some of my reasoning from above is wrong. Does <code>Parallel.Invoke</code> work differently than what I described above? If yes, how?</p>