2015-06-01 138 views
3

我正在关注如何创建将在我的Web服务器上发送自动电子邮件的Windows服务的教程。但是,我已经学习了该教程,但示例代码每60分钟执行一次服务,而我希望每天早上9点每24小时执行一次服务。C#定时器间隔每24小时

下面是示例代码

private Timer scheduleTimer = null; 
    private DateTime lastRun; 
    private bool flag; 

    public StarEmailService() 
    { 
     InitializeComponent(); 
     if (!System.Diagnostics.EventLog.SourceExists("EmailSource")) 
     { 
      System.Diagnostics.EventLog.CreateEventSource("EmailSource", "EmailLog"); 
     } 
     eventLogEmail.Source = "EmailSource"; 
     eventLogEmail.Log = "EmailLog"; 

     scheduleTimer = new Timer(); 
     scheduleTimer.Interval = 1 * 5 * 60 * 1000; 
     scheduleTimer.Elapsed += new ElapsedEventHandler(scheduleTimer_Elapsed); 

    } 

    protected override void OnStart(string[] args) 
    { 
     flag = true; 
     lastRun = DateTime.Now; 
     scheduleTimer.Start(); 
     eventLogEmail.WriteEntry("Started"); 
    } 

    protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     if (flag == true) 
     { 
      ServiceEmailMethod(); 
      lastRun = DateTime.Now; 
      flag = false; 
     } 
     else if (flag == false) 
     { 
      if (lastRun.Date < DateTime.Now.Date) 
      { 
       ServiceEmailMethod(); 
      } 
     } 
    } 

线scheduleTimer.Interval = 1 * 5 * 60 * 1000;似乎是它设置的时间间隔60分钟的代码,但是,我不确定我会需要,以修订本,以使其运行每上午9点24小时?

任何意见,将不胜感激。

谢谢。

+1

如果你关心挂钟时间,计时器是错误的工具为了工作。你想要一个调度程序。而且,如果您的服务的唯一目的是要等到预定的时间,然后运行有用的代码,则最好创建一个计划任务,并且不要让代码(无意义地)在其余时间运行。 –

+0

@Damien_The_Unbeliever谢谢,有用的评论。 – tgriffiths

回答

10

你有两个选择:

不要依赖于其他定时器,因为他们将不同步的(近)的未来。

2

将计时器设置为较小的间隔可能会更好,并检查与您的代码现在类似的系统时间。此代码应在每天上午9点或之后发送一封电子邮件。定时器间隔越小,到上午9点就越准确。例如,如果您将计时器间隔保持在60分钟,则该服务将每小时检查一次系统时间,并在上午9点到上午10点之间发送电子邮件。如果您将计时器设置为10分钟,则服务将在每个分钟时间检查一次系统时间,并在上午9:00至上午9点10分之间发送电子邮件。

这种方法不会随时间而失去同步,因为它使用系统时钟,而不是定时器间隔来知道何时触发。

删除lastRun DateTime字段及其对它的所有引用。删除标志字段和引用。添加一个名为nextRun日期时间字段:

private DateTime nextRun = DateTime.MinValue; 

添加功能GetNextRun:

private static DateTime GetNextRun(DateTime lastRun) 
{ 
    var next = lastRun.AddDays(1); 
    return new DateTime(next.Year, next.Month, next.Day, 9, 0, 0); 
} 

变化ScheduleTimer消逝于:

protected void scheduleTimer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    if (DateTime.Now < nextRun) return; 

    nextRun = GetNextRun(DateTime.Now); 
    ServiceEmailMethod(); 
}