c#确实1.09:00:00的时间跨度意味着明天上午9点?

时间:2012-06-20 07:58:49

标签: c# datetime timer timespan

我有一个例程,假设每天上午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点?

2 个答案:

答案 0 :(得分:7)

1.09:00:00表示时间跨度为1天9小时

答案 1 :(得分:4)

来自MSDN Documentation:

  

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点开始,所以如果这很重要,那么调查我提到的一个链接调度库可能会更好。