一定周期のループを安定させる方法(C#用メモ)

一定周期の処理を行いたいとき、タイマーを使えば良いのですが、より精度の高い周期で処理を行いたい場合は、次のような方法が考えられます。
これはゲームなどで、1フレーム(1回の画面の更新)の長さを1/60秒に保つために、良く用いられる方法です。

// 次に処理するフレームの時刻(初回は即処理するので初期値は現在時刻をセット)
double nextFrame = (double)System.Environment.TickCount;
// フレームを処理する周期(1/60秒)
float period = 1000f / 60f;

// メインループ
while ( true )
{
    // 現在の時刻を取得
    double tickCount = (double)System.Environment.TickCount;

    // 次に処理するフレームの時刻まで間がある場合は、処理をスキップする
    if (tickCount < nextFrame)
    {
        // 1ms以上の間があるか?
        if (nextFrame - tickCount > 1)
        {
            // Sleepする
            System.Threading.Thread.Sleep( (int)(nextFrame - tickCount) );
        }
        // Windowsメッセージを処理させる
        Application.DoEvents();
        // 残りの処理をスキップする
        continue;
    }

    // 
    // ここで描画以外の計算処理を行う。
    // 

    // この時点で現在の時刻が次のフレームの時刻より後ならば、
    // このフレームを描画している暇はないので、描画しないでスキップする
    if ((double)System.Environment.TickCount >= nextFrame + period)
    {
        nextFrame += period;
        continue;
    }

    // 
    // ここで描画処理を行う。
    // 

    // 次のフレームの時刻を計算する
    nextFrame += period;
}