Я столкнулся с проблемой, когда событие Elapsed запускается до интервала. У меня есть интервал, установленный, скажем, 10000 мс, и событие срабатывает примерно в 4500 мс. Я знаю, что этот конкретный таймер не слишком точен, но я точно знаю, что он намного точнее, чем то, что он показывает.Игнорированное событие System.Timers.Timer слишком рано
Я проверил, чтобы не было более одного таймера, вызывающего это событие. Это решение отлично работает на двух из трех окон, на которых он установлен.
Может быть проблема с версией .NET, CLR версии и т.д.
Я знаю, что есть и другие способы достижения этого, но я просто искал предложения относительно того, что может быть причиной этого, чтобы работать на всего 2 из 3 серверов.
Ниже я создаю таймер только один раз при запуске службы ..
checkTimer = new System.Timers.Timer(getSecondsLeft());
checkTimer.Elapsed += checkNowEvent;
checkTimer.AutoReset = true;
checkTimer.Enabled = true;
Вот метод, который используется, чтобы вычислить количество миллисекунд до следующей минуты
private double getSecondsLeft()
{
DateTime now = DateTime.Now;
// Has a chance to trigger a few milliseconds before new minute. Added 50ms to interval
return ((60 - now.Second) * 1000 - now.Millisecond) + 50;
}
И, наконец, прошедшее время.
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
// Start timer again
checkTimer.Enabled = true;
}
}
Я просто сделал еще несколько тестов с этим, и я добавил некоторые функции секундомера, чтобы увидеть, если интервал был на самом деле стрелять, когда предполагается, и это выглядит, как она есть. Однако, когда я вычисляю правильное количество миллисекунд на следующую минуту, НО работает так, как если бы эта реализация Таймера работала быстрее, чем системные часы ... Если это имеет смысл.
Вот код, который я использовал для этого.
private void checkNowEvent(object sender, ElapsedEventArgs e)
{
stopWatch.Stop();
_Log.LogDebug(stopWatch.Elapsed.ToString());
try
{
// Stop timer to keep from firing this event again
checkTimer.Enabled = false;
// DOING WORK HERE
}
catch (Exception ex)
{
// CATCHING EXCEPTIONS HERE IF ANY
}
finally
{
// Set the interval as to tick on the start of the next minute
checkTimer.Interval = getSecondsLeft();
_Log.LogDebug(checkTimer.Interval.ToString());
// Start timer again
checkTimer.Enabled = true;
stopWatch.Reset();
stopWatch.Start();
}
}
Протестировано это на моей стороне, оно тикает ровно через 00 секунд каждую минуту. Кроме того, System.Timers.Timer не очень точен, но он БОЛЬШЕ точнее, чем 5.5 секунд. –
Какие версии .NET установлены на 3 машинах? Это может быть хорошим местом для начала. – Cemafor
Подобный вопрос с некоторой информацией [здесь] (http://stackoverflow.com/a/2432601/5095502) – Quantic