неточный таймер .NET?

2

Я разрабатываю приложение, и мне нужно получить текущую дату с сервера (он отличается от машинной даты). Я получаю дату с сервера и с простым Split я создаю новую DateTime:

globalVars.fec = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(infoHour[0]), int.Parse(infoHour[1]), int.Parse(infoHour[2]));

globalVars - это класс, а fec - общедоступная статическая переменная, поэтому я могу получить к нему доступ в любом месте приложения (плохое кодирование, которое я знаю...). Теперь мне нужно установить таймер, если эта дата равна некоторым датам, которые я сохранил в списке, и если он равен, я просто вызываю функцию.

List<DateTime> fechas = new List<DateTime>();

Прежде чем получать дату с сервера, я использовал дату компьютера, поэтому, чтобы проверить, соответствуют ли даты, я использовал это:

private void timerDatesMatch_Tick(object sender, EventArgs e)
{
    DateTime tick = DateTime.Now;
    foreach (DateTime dt in fechas)
    {
        if (dt == tick)
        {
            //blahblah
        }
    }
}

Теперь у меня есть дата с сервера, поэтому DateTime.Now нельзя использовать здесь. Вместо этого я создал новый таймер с Interval = 1000 и по тику. Я добавляю 1 секунду к globalVars.fec, используя:

globalVars.fec = globalVars.fec.AddSeconds(1);

Но часы не точны, и каждые 30 минут часы теряют около 30 секунд.

Есть ли другой способ делать то, что я пытаюсь сделать? Я подумал об использовании threading.timer, но мне нужно иметь доступ к другим потокам и нестатическим функциям.

  • 1
    У меня на самом деле есть сервер времени, мне просто нужно приложение, чтобы использовать это время с сервера, а не компьютера
  • 0
    C # не имеет таймеров. .NET Framework делает.
Теги:
timer

3 ответа

8
Лучший ответ

Храните разницу между временем сервера и местным временем. Рассчитайте время серверов, когда вам это нужно, используя эту разницу.

  • 0
    Я не думал об этом, я просто думал о сложных решениях, когда настоящее решение было довольно простым. Спасибо!
  • 0
    Да, но это нужно периодически калибровать.
Показать ещё 2 комментария
6

Если вы создаете atimer с интервалом в 1000 мс, он будет называться не раньше, чем 1000 мс. Таким образом, вы можете в значительной степени гарантировать, что он будет вызван более чем на 1000 мс, а это означает, что вы потеряете время, добавив 1 сек в этот таймер. Это будет накапливать ошибку при каждом тике. Лучшим подходом является запись времени начала и использование текущего времени для определения текущего смещения от этого известного времени начала, так что вы не будете накапливать какую-либо ошибку в своем времени. (Там все равно будет некоторая ошибка, но вы не будете выходить из касания в реальном времени с течением времени)

Различные таймеры (Forms.Timer, Thread.Timer и т.д.) также будут иметь другую точность - Forms.Timer особенно плох для точности.

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

2

Вот надежный таймер 1 мкс

См. https://stackoverflow.com/questions/15725711/obtaining-microsecond-precision-using-net-without-platform-invoke?noredirect=1#comment22341931_15725711

Я гарантирую его более быструю и точную, чем StopWatch и PerformanceCounters, и использует доли секунды, которые у вас есть во временном разрезе с умом!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню