.NETでThreading.Thread.Sleepを使用する場合、Threading.Thread.Sleep(timeout As TimeSpan)を使用するオプションがあります。現在、System.TimeSpanには、期間を100ナノ秒単位で表すオプションがあります:System.TimeSpan(ticks as long)。Threading.Thread.Sleepはナノ秒で動作しますか、それともミリ秒(整数)に変換しますか?それらをミリ秒に変換する場合、1ミリ秒未満の間スレッドを中断する方法はありません。そうですか?
2 に答える
あなたの仮定は正しく、MSDNに文書化されています:
このスリープの過負荷は、タイムアウトでミリ秒全体の合計数を使用します。小数ミリ秒は破棄されます。
そして、私の理解では、マルチタスクの性質上、ミリ秒の値でさえ、必ずしもミリ秒までの非常に正確なスリープ時間をもたらすとは限りません。非常に特定の時間スリープする必要がある場合、次のようなコードを使用しました。
long freq;
long frame;
freq = System.Diagnostics.Stopwatch.Frequency;
frame = System.Diagnostics.Stopwatch.GetTimestamp();
while ((frame - fpsStartTime) * fps < freq * fpsFrameCount)
{
int sleepTime = (int)((fpsStartTime * fps + freq * fpsFrameCount - frame * fps) * 1000 / (freq * fps));
if (sleepTime > 0) System.Threading.Thread.Sleep(sleepTime);
frame = System.Diagnostics.Stopwatch.GetTimestamp();
}
if (++fpsFrameCount > fps)
{
fpsFrameCount = 0;
fpsStartTime = frame;
}
それは「依存する」カテゴリに分類されます。たとえば、Macで実行されるSilverlightアプリで使用することができます。ただし、標準のWindowsデスクトップアプリは、ミリ秒単位でのみ表されるスリープ時間を受け入れるオペレーティングシステムのSleep()呼び出しを使用します。
これで終わりではありません。デフォルトでは、Windowsはオペレーティングシステムのクロック割り込みに依存する精度でのみスレッドをスリープできます。これは、デフォルトでは1/64秒で、ほとんどのマシンでは0.015625秒です。したがって、Thread.Sleep(1)を実行すると、実際には約16ミリ秒スリープします。以上。
timeBeginPeriod(1)をピンボークすることで、割り込み率を上げることができます。スケジュールの不正確さにより、スリープは1ミリ秒プラスマイナスの精度になりました。バッテリー駆動のマシンでは絶対にやるべきではないこと。そして、timeEndPeriod()をピンボークすることを忘れないでください。