Thread.Sleep()の解像度は1から15.6msまで変化します
このコンソールアプリを考えると:
class Program
{
static void Main()
{
int outer = 100;
int inner = 100;
Stopwatch sw = new Stopwatch();
for (int j = 0; j < outer; j++)
{
int i;
sw.Restart();
for (i = 0; i < inner; i++)
Thread.Sleep(1);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
}
}
}
出力は100に近い100の数値になると予想しました。代わりに、次のようになります。
99 99 99100 99 99 99106106 99 99 99100100 99 99 99 99101 99 99 99 99 99101 99 99 99 99101 99 99 99100 99 99 99 99 99103 99 99 99 99 100 99 99 99 99 813 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1559 1560 1559 1559 1559 1559 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1558 1559 1558 1558 1558
しかし、正確な結果が得られない場合があります。毎回〜1559になります。
なぜ一貫していないのですか?
いくつかのグーグルは、15.6msがタイムスライスの長さであることを私に教えてくれたので、それは〜1559の結果を説明しています。しかし、なぜ私は時々正しい結果を得るのですか、そして他の時には私はちょうど15.6の倍数を得るのですか?(たとえば、Thread.Sleep(20)は通常〜31.2msを与えます)
ハードウェアまたはソフトウェアによってどのように影響を受けますか?
私がそれを発見した理由のためにこれを尋ねます:
私は32ビットのデュアルコアマシンでアプリケーションを開発していました。今日、私のマシンは完全なOSの再インストールで64ビットクアッドコアにアップグレードされました。(どちらの場合もWindows7と.NET4ですが、古いマシンにW7 SP1が搭載されているかどうかはわかりませんが、新しいマシンには搭載されています。)
新しいマシンでアプリケーションを実行すると、フォームがフェードアウトするのに時間がかかることにすぐに気付きます。10から50までの値でThread.Sleep()を使用する、フォームをフェードするカスタムメソッドがあります。古いシステムでは、これは毎回完全に機能するように見えました。新しいシステムでは、フェードするのに必要以上に時間がかかります。
この動作が古いシステムと新しいシステムの間で変わったのはなぜですか?これはハードウェアに関連していますか、それともソフトウェアに関連していますか?
一貫して正確にすることはできますか?(〜1msの解像度)
Thread.Sleep()を約1msまで確実に正確にするために、プログラムでできることはありますか?それとも10ms?