У меня есть 2 компьютера, время которых синхронизируется через NTP, который гарантирует, что время будет отличаться только на несколько миллисекунд.Один из компьютеров отправит сообщение через TCP на другой, чтобы запустить определенную функцию c # в определенное время в будущем на обоих компьютерах.
Мой вопрос: как я могу вызвать функцию в C # вопределенное время с точностью до миллисекунды (или лучше)?Мне нужно сделать это в программном коде (так что Task Scheduler или другая внешняя программа не поможет).Я думаю, что всегда повторять цикл в отдельном потоке для сравнения текущего времени с целевым временем не было бы хорошим решением.
ОБНОВЛЕНИЕ:
DateTime.Now не может использоватьсяв решении, поскольку оно имеет низкое разрешение.
Кажется, что Thread.Sleep () может быть принудительно иметь разрешение в 1 мс, импортируя:
[DllImport("winmm.dll", EntryPoint="timeBeginPeriod")]
public static extern uint MM_BeginPeriod(uint uMilliseconds);
и используя:
MM_BeginPeriod(1);
Чтобы вернуться к предыдущему разрешению, импортируйте:
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
public static extern uint MM_EndPeriod(uint uMilliseconds);
и используйте:
MM_EndPeriod(1);
ОБНОВЛЕНИЕ 2:
Iпротестировал Thread.Sleep () со многими значениями, и, похоже, что в среднем он будет стремиться к указанному промежутку времени.
Вызов Thread.Sleep () только один раз обычно остается около половины мс вокруг целевого значенияпромежуток времени, поэтому он довольно точен с точностью до миллисекунды.
Использование методов winmm.dll timeBeginPeriod и timeEndPeriod, похоже, не влияют на точность результата.
РЕШЕНИЕ:
Одним из способов будет использование timeSetEvent (устарело) или CreateTimerQueueTimer.
В настоящее время проблема заключается в том, что обеим параметрам в качестве параметра требуется время, оставшееся до срабатывания функции, а не время, в которое она должна срабатывать.Таким образом, задержка до желаемого времени для триггера должна быть рассчитана, но DateTime.Now предлагает низкое разрешение.Я нашел класс, который позволяет получать текущее DateTime в высоком разрешении.Таким образом, теперь оставшееся время можно рассчитать с высоким разрешением и передать в качестве параметра CreateTimerQueueTimer.