簡體   English   中英

定時器間隔為數月

[英]Timer with interval of multiple months

我有一個Windows服務處理由System.Timers.Timer觸發的事件。 我想將該計時器的間隔設置為3個月。

System.Timers.Timer的Interval屬性是以毫秒為單位的Int32,而Int32.MaxValue小於3個月(以毫秒為單位)。

我該怎么辦?

你會重新考慮你的設計。 存儲下次要執行事件時(例如注冊表,文件,數據庫等),然后定期喚醒以檢查是否已經過了該時間。 即使您可以將System.Timers.Timer設置為3個月,系統也可能會在計時器關閉之前重新啟動並且您將丟失事件。

另一種選擇是使用Windows Scheduler執行的預定作業。 它會運行一個小程序,向您的服務發送一條消息,說明事件已經發生。 這比資源密集程度更低 - 雖然更復雜 - 而不是定期醒來檢查3個月是否已經過去。

您無法連續運行PC 3個月。 如果應用程序關閉,計時器也將關閉。 在重新啟動應用程序時,計時器從開始重新啟動。

如果要以3個月的間隔觸發事件,則必須保留有關退出應用程序時計時器所用總時間的信息。

更新

因此,你必須在某些部分划分你的間隔,並在每次經過時設置一個計數器並增加它。每次檢查它,直到達到3個月。

例如

    int interval = 10 * 24 * 60 * 60 * 1000; // Time interval for 10 days 
    int counter = 0;
    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        counter++;
        if (counter == 9) 
        {
            //do your task for 3 months
            //since counter increments 9 times at interval of 10 days
            //so 9*10=90 days i.e. nearly equal to 3 months
            counter = 0;
        }
    }

我會使用Quartz.net - 開源企業作業調度程序 - http://quartznet.sourceforge.net/

你可以使用CRON之類的語法 - http://quartznet.sourceforge.net/tutorial/lesson_6.html並且你可以輕松地將相關的工作狀態存儲到數據庫中(只是讓機器死掉,它會發生) - http:// quartznet .sourceforge.net / tutorial / lesson_9.html ,還有更多實用性。

我在幾個生產系統上使用了Quartz.net,據我所知,這些流程今天仍在運行:)

為什么不使用System.Timer - http://quartznet.sourceforge.net/faq.html#whynottimer

祝好運!

有同樣的問題,除了它是一個通用系統可以用完全可調節的間隔做同樣的事情,從幾毫秒到幾個月。 好吧, 應該是。 事實證明,由於這個原因,它確實在大於24.8天的間隔內搞砸了。

就我而言,“重新思考方法”是不可能的,因為它只是一個更大的Windows服務系統的一個小問題子案例。

解決方案相當簡單,但請注意我有一個輔助系統,它為我提供了下一次執行DateTime ; 計時器的工作只是為了匹配實際執行任務,所以它只是通過從中減去DateTime.Now來計算間隔。

在這種情況下,我需要做的就是在我的計時器對象旁邊保留一個溢出布爾值,並在檢查Int32.MaxValue間隔時設置它:

private Timer _timer;
private Boolean _overflow;

private void QueueNextTime(DateTime thisTime)
{
    TimeSpan interval = this.GetNextRunTime(thisTime) - DateTime.Now;
    Int64 intervalInt = (Int64)((interval.TotalMilliseconds <= 0) ? 1 : interval.TotalMilliseconds);
    // If interval greater than Int32.MaxValue, set the boolean to skip the next run. The interval will be topped at Int32.MaxValue.
    // The TimerElapsed function will call this function again anyway, so no need to store any information on how much is left.
    // It'll just repeat until the overflow status is 'false'.
    this._overflow = intervalInt > Int32.MaxValue;
    this._timer.Interval = Math.Min(intervalInt, Int32.MaxValue);
    this._timer.Start();
}

// The function linked to _timer.Elapsed
private void TimerElapsed(object sender, ElapsedEventArgs e)
{
    this._timer.Stop();
    if (this._overflow)
    {
        QueueNextTime(e.SignalTime);
        return;
    }

    // Execute tasks
    // ...
    // ...

    // schedule next execution
    QueueNextTime(e.SignalTime);
}

當然,這是簡化的; 真正的系統有try / catch和一個系統來中止外部停止命令。 但這就是它的要點。

我將創建一個exe應用程序並作為計划的Windows任務的一部分運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM