为什么用 Thread.Sleep 检查秒表似乎不准确?
Why Stopwatch seems to be inaccurate if checked with Thread.Sleep?
我尝试实现 .NET Stopwatch
是为了好玩,但我得到了一些意想不到的结果。
我完全期望这个程序的执行时间大约为 100 毫秒。
是 Stopwatch
class 不准确还是这里发生了什么?
代码:
namespace Timer
{
class Program
{
Stopwatch s = new Stopwatch();
static void Main(string[] args)
{
s.Start();
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1);
}
s.Stop();
Console.WriteLine("Elapsed Time " + s.ElapsedMilliseconds + " ms");
Console.ReadKey();
}
}
}
结果是190 ms
因为Thread.Sleep(n)
意味着:至少 n 毫秒。
前段时间I wrote an answer (on another topic though), which contained an external reference:
Thread.Sleep(n)
means block the current thread for at least the number
of timeslices (or thread quantums) that can occur within n
milliseconds.
The length of a timeslice is different on different versions/types of
Windows and different processors and generally ranges from 15 to 30
milliseconds. This means the thread is almost guaranteed to block for
more than n
milliseconds. The likelihood that your thread will
re-awaken exactly after n
milliseconds is about as impossible as
impossible can be. So, Thread.Sleep
is pointless for timing.
根据MSDN:
The system clock ticks at a specific rate called the clock resolution.
The actual timeout might not be exactly the specified timeout, because
the specified timeout will be adjusted to coincide with clock ticks.
因为你不是实时的OS,你的程序可能会被其他东西打断,使用 Sleep 会增加这种情况发生的几率,即使你线程等待的毫秒数也会至少 n 毫秒。尝试使用普通的 Thread.Sleep(100),您可能会找到更接近的东西。
我尝试实现 .NET Stopwatch
是为了好玩,但我得到了一些意想不到的结果。
我完全期望这个程序的执行时间大约为 100 毫秒。
是 Stopwatch
class 不准确还是这里发生了什么?
代码:
namespace Timer
{
class Program
{
Stopwatch s = new Stopwatch();
static void Main(string[] args)
{
s.Start();
for (int i = 0; i < 100; i++)
{
Thread.Sleep(1);
}
s.Stop();
Console.WriteLine("Elapsed Time " + s.ElapsedMilliseconds + " ms");
Console.ReadKey();
}
}
}
结果是190 ms
因为Thread.Sleep(n)
意味着:至少 n 毫秒。
前段时间I wrote an answer (on another topic though), which contained an external reference:
Thread.Sleep(n)
means block the current thread for at least the number of timeslices (or thread quantums) that can occur withinn
milliseconds. The length of a timeslice is different on different versions/types of Windows and different processors and generally ranges from 15 to 30 milliseconds. This means the thread is almost guaranteed to block for more thann
milliseconds. The likelihood that your thread will re-awaken exactly aftern
milliseconds is about as impossible as impossible can be. So,Thread.Sleep
is pointless for timing.
根据MSDN:
The system clock ticks at a specific rate called the clock resolution. The actual timeout might not be exactly the specified timeout, because the specified timeout will be adjusted to coincide with clock ticks.
因为你不是实时的OS,你的程序可能会被其他东西打断,使用 Sleep 会增加这种情况发生的几率,即使你线程等待的毫秒数也会至少 n 毫秒。尝试使用普通的 Thread.Sleep(100),您可能会找到更接近的东西。