Точный таймер Windows? System.Timers.Timer () ограничен 15 мс - PullRequest
2 голосов
/ 16 января 2009

Мне нужен точный таймер для подключения приложения Windows к лабораторному оборудованию.

Я использовал System.Timers.Timer () для создания таймера, который срабатывает каждые 10 мсек, но эти часы работают медленно. Например, 1000 тактов с интервалом в 10 мсек должны занять 10 секунд настенных часов, но на самом деле это больше, чем 20 секунд настенных часов (на моем ПК). Я предполагаю, что это потому, что System.Timers.Timer () является интервальным таймером, который сбрасывается каждый раз, когда он истекает. Поскольку между истечением таймера и его сбросом (до следующих 10 мсек) всегда будет идти некоторое время, часы будут работать медленно. Это, вероятно, хорошо, если интервал большой (секунды или минуты), но недопустим для очень коротких интервалов.

Есть ли в Windows функция, которая будет запускать процедуру каждый раз, когда системные часы пересекают границу 10 мс (или что-то еще)?

Это простое консольное приложение.

Спасибо

Norm

ОБНОВЛЕНИЕ: System.Timers.Timer () крайне неточно для небольших интервалов.

Я написал простую программу, которая насчитала 10 секунд несколькими способами:

Интервал = 1, Счет = 10000, Время выполнения = 160 с, мс на интервал = 16

Интервал = 10, Счет = 1000, Время выполнения = 16 секунд, мс на интервал = 15

Интервал = 100, Счет = 100, Время выполнения = 11 с, мс на интервал = 110

Интервал = 1000, Счет = 10, Время выполнения = 10 секунд, мс на интервал = 1000

Кажется, что System.Timers.Timer () не может работать быстрее, чем около 15 мсек, независимо от настройки интервала.

Обратите внимание, что ни в одном из этих тестов не использовалось измеряемое время ЦП, поэтому ограничение - это не ЦП, а ограничение .net (ошибка?)

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

Я также нашел условно-бесплатный продукт ZylTimer.NET, который утверждает, что он является гораздо более точным таймером .net (разрешение 1-2 мсек). Это может быть то, что мне нужно. Если есть один продукт, вероятно, есть другие.

Еще раз спасибо.

Ответы [ 6 ]

4 голосов
/ 16 января 2009

На первый взгляд, это что-то вроде «таймера высокого разрешения», но это неверно. Ответ требует регулярной генерации тиков, а API счетчика производительности Windows с высоким разрешением такой тик не генерирует.

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

4 голосов
/ 16 января 2009

Вам необходимо использовать таймер высокого разрешения , такой как QueryPerformanceCounter

2 голосов
/ 05 апреля 2014

Ограничение дается системным пульсом. Обычно это значение по умолчанию составляет 64 удара / с, что составляет 15,625 мс. Однако есть способы изменить эти общесистемные настройки для достижения разрешения таймера до 1 мс или даже до 0,5 мс на новых платформах:

  1. Переход на разрешение 1 мс с помощью интерфейса мультимедийного таймера (timeBeginPeriod()):

    См. Получение и настройка разрешения таймера .

  2. Переход к разрешению 0,5 мс с помощью NtSetTimerResolution():

    См. Внутри таймеров высокого разрешения Windows NT .

Вы можете получить разрешение 0,5 мс с помощью скрытого API NtSetTimerResolution().

Я дал все детали в этом ТАКом ответе.

2 голосов
/ 16 января 2009

В System.Diagnostics вы можете использовать класс Секундомер .

1 голос
/ 16 января 2009
1 голос
/ 16 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...