我已经完成了编写程序的任务,以计算从我们的网站请求的页面浏览量。我目前的方法是从谷歌分析实时API获取数据,这对我的惊喜很有用。
我的问题是,为了每分钟获取网页浏览量,我需要两次从Google API轮询数据(导致它返回最后29分钟的总和+来自每分钟重置的计时器的值)。在我设置了重置点之后,我只想说,每分钟第55秒,我在第56次和之后的第53秒轮询数据,这给了我相对较好的新用户/页面估计请求的意见。
所以这是我目前的做法:
static System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.AutoReset = false;
myTimer.Interval = interval();
myTimer.Elapsed += myTimer_Elapsed2;
myTimer.Start();
static double interval()
{
return 1000 - DateTime.Now.Millisecond;
}
static void myTimer_Elapsed2(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now.Second == (resetPoint.Second - 1) % 60 && warden)
{
DoStuff(); //mostly inserting google API data to database
}
else if (DateTime.Now.Second == (resetPoint.Second + 1) % 60) //so we dont get riddiculous 60 and above
{
//I get some data here, to later use it in DoStuff - mostly to calculate the gap between later
}
myTimer.Interval = interval(); //Because DoStuff() takes about 0.5 sec to execute, i need to recalibrate
myTimer.Start();
}
它的效果非常好,直到它在大约2个小时后停止,现在我不知道为什么(程序运行,只是计时器不再进行其工作)。
如何让它长时间保持稳定?最好的情况是在没有干预的情况下运行数月。
@我编辑以更好地理解我实际在做什么
@END CREDITS
我最终使用了两个计时器,每个计时器都运行一分钟。数据库写入有时会崩溃,我没有正确处理相应的异常。 Log告诉我谷歌API函数不时倾向于检索数据更长一点,这导致多个Threading.Event调用并使我的数据库数据处理抛出异常因此停止计时器。
我尝试使用Quartz方法,但缺乏人性化的方法让我放弃了这个库。
答案 0 :(得分:3)
您应该真正考虑使用Quartz.net在可靠的基础上安排事件。使用计时器进行调度会询问竞争条件,事件跳过和数据库死锁等内容。
http://www.quartz-scheduler.net/允许您以精确的时间间隔安排事件,与代码启动或停止时无关。
关于如何使用它的示例:这将构建一个触发器,它将在下一个小时的顶部触发,然后每2小时重复一次,永远:
trigger = TriggerBuilder.Create()
.WithIdentity("trigger8") // because group is not specified, "trigger8" will be in the default group
.StartAt(DateBuilder.EvenHourDate(null)) // get the next even-hour (minutes and seconds zero ("00:00"))
.WithSimpleSchedule(x => x
.WithIntervalInHours(2)
.RepeatForever())
// note that in this example, 'forJob(..)' is not called
// - which is valid if the trigger is passed to the scheduler along with the job
.Build();
scheduler.scheduleJob(trigger, job);
http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/simpletriggers.html有一些例子。我真的很想让你使用它,因为它会严重简化开发。
答案 1 :(得分:1)
.NET计时器是可靠的。也就是说,它不会因为没有明显的原因而随意停止工作。
最有可能的是,您的计时器事件处理程序中的某些内容正在抛出异常,但由于System.Timers.Timer
压缩了异常,因此异常没有浮出水面。正如the documentation所述:
Timer组件捕获并抑制事件处理程序为Elapsed事件抛出的所有异常。在将来的.NET Framework版本中,此行为可能会发生更改。
关于行为的一点点"可能会发生变化"自从至少.NET 2.0以来一直存在。
我认为发生的事情是计时器调用您的事件处理程序。事件处理程序或它调用的方法之一会引发异常,而计时器只是将它放在地板上,因为你不会处理它。
您需要在myTimer_Elapsed2
方法中放置一个异常处理程序,以便至少可以记录任何突然出现的异常。使用异常日志中提供的信息,您可以确定问题所在。
更好的是,停止使用System.Timers.Timer
。请改用System.Threading.Timer。
最后,你所编写的代码无法在每分钟的最后55分钟给你一个计时器滴答。计时器并不准确。它将每分钟关闭几毫秒。随着时间的推移,它将开始在54秒(或56),然后53(或57)等开始滴答。如果你真的需要这个在55分钟后可靠地打勾,那么你&#39 ; ll需要在每分钟后重置计时器,并考虑当前时间。
我怀疑你需要在确切的55秒标记处检查每一分钟都是矫枉过正。只需将计时器设置为每分钟打勾,然后确定自上次打勾以来的确切经过时间。所以一分钟"分钟#34;可能是61或62秒,另一个可能是58或59秒。如果您存储请求数和经过的时间,后续处理可以平滑颠簸并为您提供可靠的每分钟请求数。尝试在精确一分钟边界上收集数据将非常困难,即使对于像Windows这样的非实时操作系统也是如此。