每24小时C#计时器间隔

时间:2015-06-01 08:58:15

标签: c# timer windows-services

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

以下是示例代码

    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小时运行一次?

任何建议都将受到赞赏。

感谢。

2 个答案:

答案 0 :(得分:10)

您有几种选择:

不要依赖其他计时器,因为他们将来(近)将失去同步。

答案 1 :(得分:4)

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

此方法不会随着时间的推移而失去同步,因为它使用系统时钟,而不是计时器间隔来知道何时触发。

删除lastRun DateTime字段及其所有引用。删除标志字段和引用。添加名为nextRun的DateTime字段:

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();
}