我的系统每天需要在午夜更新数据库。
该值是每日使用量计数器。
为此,我对此类进行了编码:
internal class MidnightTimer
{
internal event EventHandler Elapsed = delegate { };
private Timer timer;
internal MidnightTimer()
{
timer = new Timer();
timer.Elapsed += timer_Elapsed;
}
internal void Start()
{
TimeSpan timeSpanToMidnight = GetNextMidnight().Subtract(DateTime.Now);
timer.Interval = timeSpanToMidnight.TotalMilliseconds;
timer.Start();
}
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
Elapsed(this, EventArgs.Empty);
timer.Stop();
Start();
}
private static DateTime GetNextMidnight()
{
const string datePattern = "dd/MM/yyyy hh:mm:ss";
const string dateFormat = "{0:00}/{1:00}/{2:0000} {3:00}:{4:00}:{5:00}";
DateTime nextMidnight;
string dateString = string.Format(dateFormat, DateTime.Now.Day + 1, DateTime.Now.Month, DateTime.Now.Year, 0, 0, 0);
bool valid = DateTime.TryParseExact(dateString, datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out nextMidnight);
if (!valid)
{
dateString = string.Format(dateFormat, 1, DateTime.Now.Month + 1, DateTime.Now.Year, 0, 0, 0);
valid = DateTime.TryParseExact(dateString, datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out nextMidnight);
}
if (!valid)
{
dateString = string.Format(dateFormat, 1, 1, DateTime.Now.Year + 1, 0, 0, 0);
DateTime.TryParseExact(dateString, datePattern, CultureInfo.InvariantCulture, DateTimeStyles.None, out nextMidnight);
}
return nextMidnight;
}
}
问题是它不准确。
有时,该事件在午夜之前几毫秒被调用,并且由于在第一个事件中将值发送到DB之后我正在重置该值,因此在第二个事件后它将重置DB中的值。
任何帮助表示赞赏。
最佳答案
您不能假定要以毫秒精度引发计时器事件。精度取决于许多因素,包括系统启动时的系统负载,进程优先级等。在这里,时钟偏移或任何时钟调整也会起作用,因为您正在计算事件那将在一整天后发生。
由于我假设事件本身并不精确,因此,将最后一个事件的时间保存在一个变量中,然后将其用于计算下一个事件,这并不重要。如果您确实必须确保每晚仅收到一个事件,那么您甚至必须将最后一个事件的时间保存在数据库中。
关于c# - C#午夜计时器过早调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21072530/