Вместо того, чтобы устанавливать время для запуска каждую секунду каждые 60 минут, вы можете рассчитать оставшееся время и установить таймер на половину (или некоторую другую долю) от этого.Таким образом, вы не столько проверяете время, сколько сохраняете степень точности, так как интервал таймера уменьшается по мере приближения к целевому времени.
Например, если вы хотите сделать что-то через 60 минут, таймерыинтервалы будут приблизительно:
30: 00: 00, 15:00:00, 07:30:00, 03:45:00, ..., 00:00:01, RUN!
Я использую приведенный ниже код для автоматического перезапуска службы один раз в день.Я использую поток, потому что я обнаружил, что таймеры ненадежны в течение длительных периодов, хотя в этом примере это более затратно, это единственный созданный для этой цели, так что это не имеет значения.
(преобразовано из VB.NET)
autoRestartThread = new System.Threading.Thread(autoRestartThreadRun);
autoRestartThread.Start();
...
private void autoRestartThreadRun()
{
try {
DateTime nextRestart = DateAndTime.Today.Add(CurrentSettings.AutoRestartTime);
if (nextRestart < DateAndTime.Now) {
nextRestart = nextRestart.AddDays(1);
}
while (true) {
if (nextRestart < DateAndTime.Now) {
LogInfo("Auto Restarting Service");
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = string.Format("/C net stop {0} && net start {0}", "\"My Service Name\"");
p.StartInfo.LoadUserProfile = false;
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.CreateNoWindow = true;
p.Start();
} else {
dynamic sleepMs = Convert.ToInt32(Math.Max(1000, nextRestart.Subtract(DateAndTime.Now).TotalMilliseconds / 2));
System.Threading.Thread.Sleep(sleepMs);
}
}
} catch (ThreadAbortException taex) {
} catch (Exception ex) {
LogError(ex);
}
}
Примечание. Я установил минимальный интервал в 1000 мс, его можно увеличитьуменьшается или удаляется в зависимости от требуемой точности.
Не забудьте также остановить поток / таймер при закрытии приложения.