A matter of timing

You know how everything time related in .NET uses milliseconds? Kind of gives you the impression you can deal with things at a millisecond resolution. Generally not so. The internal clock seems to have a resolution just a bit above 10ms, so no matter what value you use for Thread.Sleep() or as your interval for any of the three built-in timers, you achieve about 65Hz. Now, I say "generally" because while my tests on timers have returned 65Hz regardless of which machine I tried them on, Thread.Sleep(1) seemed to give me about 500Hz (still half as fast as it should be) on one machine.

For gathering timing statistics, you could always wrap the Kernel32 counters and get amazing time resolution and with .NET 2.0 you get System.Diagnostics.Stopwatch which has that high resolution as well, if Stopwatch.IsHighResolution is true. It seems to be true on every machine i've tried. But still doesn't give me a timer with the right resolution.

Thread.Sleep(0) seems to just yield execution, so a tight loop on it gives us high resolution and should let other threads work uninterrupted. But it does drive load up regardless. I guess it's a phantom load, but i can't be sure. Using System.Diagnostics.Stopwatch and Thread.Sleep(0), I whipped up a quick-and-dirty High Resolution Timer class as follows:

public class HiResTimer
{
  static Stopwatch ticktock = new Stopwatch();
  static int counter;
  static public void Test()
  {
    HiResTimer hiTee = new HiResTimer(new TimerCallback(DoSomething), 10);
    Thread.Sleep(500);
    for (int i = 0; i < 1000; i++)
    {
      Thread.Sleep(100);
      Console.Clear();
      double hz = counter \* 1000 / ticktock.ElapsedMilliseconds;
      Console.WriteLine("hz: {0:f}", hz);
    }
    hiTee.Stop();
  }

  static void DoSomething(object nullobject)
  {
    if (!ticktock.IsRunning)
    {
      ticktock.Start();
    }
    counter++;
  }

  Thread timerLoop;
  Stopwatch watch = new Stopwatch();
  bool keepTiming = true;
  TimerCallback cycleDelegate;
  int interval;

  public HiResTimer(TimerCallback timerCycle, int interval)
  {
    this.cycleDelegate = timerCycle;
    this.interval = interval;
    timerLoop = new Thread(new ThreadStart(DoLoop));
    timerLoop.Start();
  }

  public void Stop()
  {
    keepTiming = false;
    timerLoop.Join();
  }

  private void DoLoop()
  {
    while (keepTiming)
    {
      watch.Reset();
      watch.Start();
      cycleDelegate(null);
      while (watch.ElapsedMilliseconds < interval)
      {
        Thread.Sleep(0);
      }
    }
  }
}

Seems to work and the built-in static Test() method reliably runs at 100Hz, but as i mentioned, my CPU is constantly at 50%. In theory, as the cycleDelegate increases in complexity and other threads consume processing power, the idle loop of the timer should yield it's processing hunger, but I have not given this a proper test.

The real question is, is there another sleep/yield mechanism that gives me a resoltution somewhere between Thread.Sleep(0) and Thread.Sleep(1) (where 1 really ends up being more like 12 in most cases).