我有一个例程,假设每天上午9点运行....
protected override void OnStart(string[] args)
{
log.Info("Info - Service Start");
string timeToRunStr = "09:00";
var timeStrArray = timeToRunStr.Split(';');
foreach (var strTime in timeStrArray)
{
timeToRun.Add(TimeSpan.Parse(strTime));
}
ResetTimer();
}
void ResetTimer()
{
log.Info("Info - Reset Timer");
try
{
TimeSpan currentTime = DateTime.Now.TimeOfDay;
TimeSpan nextRunTime = timeToRun[0];
foreach (TimeSpan runTime in timeToRun)
{
if (currentTime < runTime)
{
nextRunTime = runTime;
// log.Info("Info - in loop");
_timer = new Timer((nextRunTime - currentTime).TotalSeconds * 1000);
break;
}
else {
TimeSpan test = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 16, 51, 0).AddDays(1).Subtract(DateTime.Now);
nextRunTime = test;
_timer = new Timer((nextRunTime).TotalSeconds * 1000);
}
}
log.Info("Info - Timer : " + (nextRunTime - currentTime).TotalSeconds * 1000);
log.Info("Info - nextRuntime : " + nextRunTime);
log.Info("Info - currentTime : " + currentTime);
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
}
catch (Exception ex)
{
log.Error("This is my timer error - ", ex);
}
}
它运行在上午9点然后下一个运行时间它说1.09:00:00这意味着明天上午9点?
答案 0 :(得分:7)
1.09:00:00表示时间跨度为1天9小时
答案 1 :(得分:4)
TimeSpan值可以表示为[ - ] d.hh:mm:ss.ff,其中 可选的减号表示负时间间隔,d 组件是天,hh是在24小时制上测量的小时数,mm是 分钟,ss是秒,ff是几分之一秒。这是一个 时间间隔由正天数或负天数组成 没有一天的时间,或一天中的时间,或只有 一天中的某个时间。
在您的实例中,TimeSpan为1天,9小时,0分钟和0秒。
回答你的实际问题:
它运行在上午9点然后下一个运行时间它说1.09:00:00这意味着什么 明天上午9点?
这取决于 - 如果您将时间跨度添加到当前时间(即当前批次结束时),则会在下一个下午6点左右给您一个时间。您需要使用DateTime.Now.Date(给定日期的午夜)并将时间跨度添加到第二天上午9点。
但是,有很多scheduling components您可能会觉得更容易使用(或至少阅读代码) - 具体取决于您对准确性和恢复的要求。
在您的原始方法中,您可能会更容易理解:
protected override void OnStart(string[] args)
{
log.Info("Info - Service Start");
DateTime startTime = DateTime.Date.AddHours(9); //9AM Today
timeToRun.Add(startTime);
CreateTimer();
}
void CreateTimer()
{
log.Info("Info - Reset Timer");
try
{
if(_timer == null){
_timer = new Timer(3600 * 1000); //once an hour
_timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
_timer.Start();
}
}
catch (Exception ex)
{
log.Error("This is my timer error - ", ex);
}
}
然后,在你的timer_elapsed事件中,你只需执行以下操作(原谅事件签名,它来自内存):
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if(DateTime.Now > timeToRun[0])
{
//Code to run the job
//Then we reset the timer - can do this here or at the end of the job code
timeToRun[0] = DateTime.Date.AddDays(1).AddHours(9); //9AM tomorrow.
}
}
你的重置计时器过于复杂 - 你不需要所有的代码。您只需创建一个计时器,让它每小时检查一次,如果时间现在大于作业运行时间,则运行该作业,并将下一个运行时间移至明天上午9点。这就是你需要为这样一个简单的计时器做的所有事情。
这种方法的问题包括它不是粒状的;这项工作可能不会在完全上午9点开始,所以如果这很重要,那么调查我提到的一个链接调度库可能会更好。