There are two differences. The first is mentioned in the MSDN docs for SwitchToThread:
The yield of execution is limited to the processor of the calling thread. The operating system will not switch execution to another processor, even if that processor is idle or is running a thread of lower priority.
Sleep(0) will allow threads on other processors to run, as well.
SwitchToThread only yields to a single thread scheduling context, as well. Sleep, on the other hand, has multiple conditions for which it waits. The docs for SleepEx spell this out in detail:
* An I/O completion callback function is called
* An asynchronous procedure call (APC) is queued to the thread.
* The time-out interval elapses
This will yield to multiple threads.
In general, Sleep(0) will be much more likely to yield a timeslice, and will ALWAYS yield to the OS, even if there are no other threads waiting. This is why adding a Sleep(0) in a loop will take the processor usage from 100% (per core) to near 0% in many cases. SwitchToThread will not, unless another thread is waiting for a time slice.