Какова максимальная точность таймера в .NET? - PullRequest
10 голосов
/ 03 октября 2009

Мне интересно, какова точность класса Timer в System.Timers, потому что он удваивается (что может указывать на то, что у вас могут быть доли миллисекунд). Что это?

Ответы [ 6 ]

9 голосов
/ 03 октября 2009

Настольные ОС Windows на самом деле не точны ниже 40 мс. ОС просто не в реальном времени и, следовательно, представляет значительный недетерминированный джиттер. Это означает, что, хотя он может сообщать значения вплоть до миллисекунды или даже меньше, вы не можете рассчитывать на то, что эти значения будут действительно значимыми. Таким образом, , даже если интервал таймера настроен на какое-то значение менее миллисекунды, вы не можете полагаться на то, что время между установкой и срабатыванием действительно соответствует желаемому.

Добавьте к этому тот факт, что весь фреймворк, на котором вы работаете, недетерминирован (GC может приостановить вас и выполнить сбор во время запуска Timer), и вы в конечном итоге столкнетесь с нагрузками и рисками, пытаясь делать все, что критично ко времени.

2 голосов
/ 03 октября 2009

Пару лет назад я обнаружил, что точность составляет около 16 мс ... но я, к сожалению, не помню деталей.

2 голосов
/ 03 октября 2009

System.Timers.Timer это странно. Он использует double как интервал, но на самом деле вызывает Math.Ceiling для него и приводит результат как int для использования с базовым System.Threading.Timer. Тогда теоретическая точность равна 1 мс, и вы не можете указать интервал, превышающий 2 147 483 647 мс. Учитывая эту информацию, я действительно не знаю, почему в качестве параметра интервала используется double.

1 голос
/ 03 октября 2009

Вы можете легко это выяснить, выполнив цикл, который постоянно измеряет полученную длительность и проверяет степень детализации.

0 голосов
/ 24 июля 2012

Разрешение таймера переходит в режим 1 мс без особых усилий по реализации. Я только что описал причину точности double в этом ответе . При настройке системы на работу с 1024 прерываниями в секунду (с использованием API мультимедийного таймера) время между прерываниями составляет 0,9765625 мс. Стандартное разрешение для синхронизации имеет значение 100 нс. Эти значения хранятся в виде целых чисел. Значение 0,9765625 не может быть сохранено без потери точности целого числа с разрешением 100 нс. Последняя цифра (5) представляет 500 пс Таким образом, разрешение должно быть на три порядка выше. Хранить это время Значения в целых числах с разрешением 100 пс безнадежны, поскольку 8-байтовое целое число при разрешении 100 пс обернулось бы всего около 21350 дней или около 58 лет. Этот промежуток времени слишком мал, чтобы быть принятым кем-либо (помните сценарий 2000 года!).

См. Ответ, связанный с, чтобы узнать больше о деталях.

0 голосов
/ 04 мая 2012

Я сравнил System.Timers.Timer и System.Threading.Timer - обе они дают систематические ошибки около 8,16 мс, особенно на небольших интервалах (1000 ... 6000 мс). Каждый последующий вызов процедуры таймера происходил с увеличенным интервалом от первого вызова. Например, таймер с интервалом 2000 мс срабатывает в 2000, 4012, 6024, 8036, 10048 миллисекунд и т. Д. (Метки времени, полученные из Environment.TickCount и Stopwatch.ElapsedTicks, дают одинаковые результаты).

...