Мне интересно, какова точность класса Timer в System.Timers, потому что это двойной (который, казалось бы, указывает, что вы можете иметь доли миллисекунд). Что это?
Какова максимальная точность таймера в .NET?
Ответ 1
Настольные ОС Windows действительно не точны ниже 40 мс. ОС просто не является реальным временем и поэтому представляет значительный недетерминированный джиттер. Это означает, что, хотя он может сообщать значения до миллисекунды или даже меньше, вы не можете рассчитывать на то, что эти значения будут действительно значимыми. Таким образом, даже если интервал таймера будет установлен на какое-то значение в миллисекундах, вы не можете полагаться на время между настройкой и стрельбой, чтобы на самом деле было то, что вы сказали, что хотите.
Добавьте к этому факту, что вся инфраструктура, в которой вы работаете, не является детерминированной (GC может приостановить вас и сделать сбор с учетом времени, когда должен срабатывать таймер), и вы в конечном итоге получаете нагрузки и нагрузки, делать все, что критично.
Ответ 2
System.Timers.Timer странно. Он использует double в качестве интервала, но на самом деле вызывает Math.Ceiling на нем и делает результат в виде int для использования с базовым System.Threading.Timer. Теоретическая точность составляет 1 мс, и вы не можете указать интервал, превышающий 2 147 483 647 мс. Учитывая эту информацию, я действительно не знаю, почему в качестве параметра интервала используется double.
Ответ 3
Пару лет назад я нашел, что это точно до 16 мс... но я, к сожалению, не помню подробностей.
Ответ 4
Вы можете легко найти это для себя, выполнив цикл, который постоянно отображает результирующую продолжительность времени и проверяет, какую степень детализации он выполняет.
Ответ 5
Я сравнивал System.Timers.Timer
и System.Threading.Timer
- оба они дают систематические ошибки около 8..16 мс, особенно на малых интервалах (1000..6000 мс). Каждый последующий вызов таймера выполнялся с увеличением интервала от первого вызова. Например, таймер с интервалом 2000 мс срабатывает в 2000, 4012, 6024, 8036, 10048 миллисекунд и т.д. (Отметки времени, полученные из Environment.TickCount
и Stopwatch.ElapsedTicks
, оба дают одинаковые результаты).
Ответ 6
Разрешение таймера переходит в режим 1 мс без особых усилий.
Я только что описал причину точности double
в этом ответе.
При настройке системы на 1024 прерываний в секунду (с использованием API таймера мультимедиа) время между прерываниями составляет 0,9765625 мс. Стандартное разрешение для сроков составляет 100 нс. Эти значения сохраняются как целые числа. Значение 0.9765625 не может быть сохранено
без потери точности в целых числах с разрешением 100 нс. Последняя цифра (5) представляет
500 пс. Таким образом, разрешение должно быть на три порядка выше. Хранение на этот раз
значения в целых числах с разрешением 100 пс являются безнадежными, поскольку 8-байтное целое число с разрешением 100 пс будет охватывать около 21350 дней или около 58 лет. Этот временной интервал слишком короткий, чтобы принять кого-либо (вспомните сценарий Y2K!).
См. ответ, связанный с тем, чтобы узнать больше о деталях.
Ответ 7
Я не знаю, как низко вы должны идти, но я нашел, казалось бы, надежный метод достижения этого в С# до 1 мкс,
Это быстрее, чем все, что вы можете придумать с верхней части головы. (StopWatch, PerformanceCounters, среди прочего)
Ответ 8
См. это для решения, которое дает вам 1 мкс время сна!
Это может даже вдохновить вас на то, чтобы сделать систему обработки ожидающих данных с точным сокером для того, что вам нужно!