title: SwitchToThread/Thread.Yield vs. Thread.Sleep(0) vs. Thead.Sleep(1)
body: <p>I am trying to write the ultimate "Yield" method to yield the current time slice to other threads. So far I have found that there are several different ways to make the thread yield its allocated time slice. I just want to make sure I am interpreting them correctly since the documentation is not very clear. So, from what I have read on stackoverflow, MSDN and various blog posts, the following options exist that all have different advantages / disadvantages:</p>
  
  <p><strong><code>SwitchToThread</code></strong> [win32] / <strong><code>Thread.Yield</code></strong> [.NET 4 Beta 1]: yields to any thread on same processor</p>
  
  <ul>
  <li>Advantage: about twice as fast as
  <code>Thread.Sleep(0)</code></li>
  <li>Disadvantage: yields only to threads
  on same processor</li>
  </ul>
  
  <p><strong><code>Thread.Sleep(0)</code>:</strong> yields to any thread of same or higher priority on any processor</p>
  
  <ul>
  <li>Advantage: faster than
  <code>Thread.Sleep(1)</code></li>
  <li>Disadvantage: yields only to threads
  of same or higher priority</li>
  </ul>
  
  <p><strong><code>Thread.Sleep(1)</code></strong>: yields to any thread on any processor</p>
  
  <ul>
  <li>Advantage: yields to any thread on
  any processor</li>
  <li>Disadvantage: slowest option
  (<code>Thread.Sleep(1)</code> will usually
  suspend the thread by about 15ms if
  <code>timeBeginPeriod</code>/<code>timeEndPeriod</code>
  [win32] are not used)</li>
  </ul>
  
  <p>What about <code>Thread.SpinWait</code>? Can that be used for yielding the time slice of the thread? If not, what is it used for?</p>
  
  <p>I there something else I have missed or incorrectly interpreted. I'd be grateful if you could correct / add to my understanding.</p>
  
  <p>This is how my Yield method looks like so far:</p>
  
  <pre><code>public static class Thread
  {
      [DllImport("kernel32.dll")]
      static extern bool SwitchToThread();
  
      [DllImport("winmm.dll")]
      internal static extern uint timeBeginPeriod(uint period);
  
      [DllImport("winmm.dll")]
      internal static extern uint timeEndPeriod(uint period);
  
      /// &lt;summary&gt;  yields time slice of current thread to specified target threads &lt;/summary&gt;
      public static void YieldTo(ThreadYieldTarget threadYieldTarget)
      {
          switch (threadYieldTarget) {
              case ThreadYieldTarget.None: 
                  break; 
              case ThreadYieldTarget.AnyThreadOnAnyProcessor:
                  timeBeginPeriod(1); //reduce sleep to actually 1ms instead of system time slice with is around 15ms
                  System.Threading.Thread.Sleep(1); 
                  timeEndPeriod(1); //undo
                  break;
              case ThreadYieldTarget.SameOrHigherPriorityThreadOnAnyProcessor:
                  System.Threading.Thread.Sleep(0); 
                  break;
              case ThreadYieldTarget.AnyThreadOnSameProcessor:
                  SwitchToThread();
                  break;
              default: throw new ArgumentOutOfRangeException("threadYieldTarget");
          }
      }
  }
  
  public enum ThreadYieldTarget
  {
      /// &lt;summary&gt;  Operation system will decide when to interrupt the thread &lt;/summary&gt;
      None,
      /// &lt;summary&gt;  Yield time slice to any other thread on any processor &lt;/summary&gt;
      AnyThreadOnAnyProcessor,
      /// &lt;summary&gt;  Yield time slice to other thread of same or higher piority on any processor &lt;/summary&gt;
      SameOrHigherPriorityThreadOnAnyProcessor,
      /// &lt;summary&gt; Yield time slice to any other thread on same processor &lt;/summary&gt;
      AnyThreadOnSameProcessor
  }
  </code></pre>