Я разрабатываю приложение, и мне нужно получить текущую дату с сервера (он отличается от машинной даты). Я получаю дату с сервера и с простым 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, но мне нужно иметь доступ к другим потокам и нестатическим функциям.
Храните разницу между временем сервера и местным временем. Рассчитайте время серверов, когда вам это нужно, используя эту разницу.
Если вы создаете atimer с интервалом в 1000 мс, он будет называться не раньше, чем 1000 мс. Таким образом, вы можете в значительной степени гарантировать, что он будет вызван более чем на 1000 мс, а это означает, что вы потеряете время, добавив 1 сек в этот таймер. Это будет накапливать ошибку при каждом тике. Лучшим подходом является запись времени начала и использование текущего времени для определения текущего смещения от этого известного времени начала, так что вы не будете накапливать какую-либо ошибку в своем времени. (Там все равно будет некоторая ошибка, но вы не будете выходить из касания в реальном времени с течением времени)
Различные таймеры (Forms.Timer, Thread.Timer и т.д.) также будут иметь другую точность - Forms.Timer особенно плох для точности.
Вы также можете использовать время высокой производительности, чтобы лучше отслеживать время - см. здесь.
Вот надежный таймер 1 мкс
Я гарантирую его более быструю и точную, чем StopWatch и PerformanceCounters, и использует доли секунды, которые у вас есть во временном разрезе с умом!