Разрешение Thread.Sleep() варьируется от 1 до 15,6 мс
Учитывая это консольное приложение:
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 99 100 99 99 99 106 106 99 99 99 100 100 99 99 99 99 101 99 99 99 99 99 101 99 99 99 99 101 99 99 99 100 99 99 99 99 99 103 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 1558 1558
Но иногда я не получаю точных результатов; это будет ~ 1559 каждый раз.
Почему это непоследовательно?
Некоторые гуглы научили меня, что 15,6 мс — это длина временного среза, так что это объясняет ~ 1559 результатов. Но почему иногда я получаю правильный результат, а иногда просто кратный 15,6? (например, Thread.Sleep(20) обычно дает ~31,2 мс)
Как на это влияет аппаратное или программное обеспечение?
Я спрашиваю это из-за того, что привело меня к его открытию:
Я разрабатывал свое приложение на 32-битной двухъядерной машине. Сегодня моя машина была обновлена до 64-битного четырехъядерного процессора с полной переустановкой ОС. (Windows 7 и .NET 4 в обоих случаях, однако я не могу быть уверен, что на старой машине был W7 SP1, а на новой есть.)
После запуска моего приложения на новой машине я сразу же заметил, что мои формы исчезают дольше. У меня есть собственный метод для затухания моих форм, который использует Thread.Sleep() со значениями от 10 до 50. В старой системе это, казалось, работало каждый раз отлично. В новой системе исчезновение занимает гораздо больше времени, чем должно.
Почему это поведение изменилось между моей старой системой и моей новой системой? Это связано с железом или софтом?
Могу ли я сделать его неизменно точным? (разрешение ~1 мс)
Есть ли что-то, что я могу сделать в своей программе, чтобы сделать Thread.Sleep() надежно точным примерно до 1 мс? Или даже 10 мс?
timeBeginPeriod(1)
/timeEndPeriod(1)
. - person Igby Largeman   schedule 01.10.2011