定时器最大间隔

时间:2015-12-02 16:25:55

标签: c# winforms timer

使用System.Windows.Form.Timer时间间隔为int,最大间隔时间限制为25天左右。我知道我可以创建一些任意算法,一旦达到限制就启动另一个计时器,但这只是愚蠢。

MISLEADING-IGNORE - >所以如果我想将它设置为29天左右(2619609112.7228003)毫秒?< - MISLEADING-IGNORE

修改

这里真正的问题是如何将System.Windows.Form.Timer设置为高于maxInt的值?

目的是我需要设置从下一个月的每个时间到第一天的间隔,因此可能是28,29,30或31天,当该间隔到期时,计算到下一个第一个的间隔这个月的某一天。

(基本上,Crystal Report将在每月的第1天运行并打印(约500页),因为报告的长度将在几小时内耗尽,因此它不会占用打印机。)

e.g。今天运行它(今天是2015年1月12日),16/1/16是下一个“月的第一天”,所以将间隔设置为从现在开始到之后的毫秒数。

1/1/16到来,所以计时器滴答,然后计算并设置1/2/2016的间隔(该月的下一个第一天)。

@SeeSharp - 我确实看到了这个问题,但我正在开发一个遗留应用程序并且不确定更改计时器的含义,但是如果我不能让这个计时器工作,我可能会看一下线程,感谢。

EDIT2:感谢您提出的所有建议,我选择了第三方插件FluentScheduler

3 个答案:

答案 0 :(得分:1)

将计时器间隔设置为一天(比如说)并使用它来计算最多29天的天数。

修改

将计时器设置为半天(比如说)并用它来检查日期是否是该月的第一天。

答案 1 :(得分:1)

月份计时器怎么样 - 当月份发生变化时,这将在接近午夜时触发。可能更适合您的要求吗? 如果我们也必须考虑日光节约,那么定时器应该在每月的第一天凌晨2点开始,所以我将使其可配置。

这是一个解释我的想法的代码 -

   public class MonthTimer : IDisposable
{

    public event EventHandler<MonthChangedEventArgs> MonthChanged;

    DateTime mLastTimerDate;
    Timer mTimer;

    public MonthTimer(TimeSpan timeOfFirstDay)
        : this(DateTime.Now, timeOfFirstDay)
    {
    }

    public MonthTimer(DateTime currentDate, TimeSpan timeOfFirstDay)
    {
        mLastTimerDate = currentDate.Date;
        var milliSecondsInDay = new TimeSpan(1, 0, 0, 0).TotalMilliseconds;

        Contract.Assert(timeOfFirstDay.TotalMilliseconds <= milliSecondsInDay); // time within 1st day of month            
        DateTime currentDateLastSecond = currentDate.Date.AddDays(1).AddTicks(-1);  // one tick before midnight 
        TimeSpan timeSpanInCurrentDate = currentDateLastSecond.Subtract(currentDate); // remaining time till today ends

        // I want the timer to check every day at specifed time (as in timeOfFirstDay) if the month has changed 
        // therefore at first I would like timer's timeout to be until the same time, following day
        var milliSecondsTillTomorrow = (timeSpanInCurrentDate + timeOfFirstDay).TotalMilliseconds;
        // since out milliseconds will never exceed - . Its okay to convert them to int32
        mTimer = new Timer(TimerTick, null, Convert.ToInt32(milliSecondsTillTomorrow), Convert.ToInt32(milliSecondsInDay));
    }

    private void TimerTick(object state)
    {
        if(DateTime.Now.Month != mLastTimerDate.Month)
        {
            if (MonthChanged != null)
                MonthChanged(this, new MonthChangedEventArgs(mLastTimerDate, DateTime.Now.Date));
        }
        mLastTimerDate = DateTime.Now.Date;
    }


    public void Dispose()
    {
        mTimer.Dispose();
    }
}

public class MonthChangedEventArgs : EventArgs
{
   public MonthChangedEventArgs(DateTime previousMonth, DateTime currentMonth)
    {
        CurrentMonth = currentMonth;
        PreviousMonth = previousMonth;
    }

   public DateTime CurrentMonth
    {
        get;
        private set;
    }

   public DateTime PreviousMonth
   {
       get;
       private set;
   }
}

客户端代码

    // Check the new month around 2 AM on 1st day
        mMonthTimer = new MonthTimer(new TimeSpan(2, 0, 0));
        mMonthTimer.MonthChanged += mMonthTimer_MonthChanged;

有一件事我没有使用System.Threading.Timer,因此偶数处理程序将在一个单独的线程&amp;如果这是一个问题,请将UI线程视为System.Windows.Forms.Timer,请告诉我。

如果它符合您的目的或任何问题

,也请写评论

答案 2 :(得分:1)

尝试Microsoft's Reactive Framework(NuGet&#34; Rx-Main&#34;)。

你可以这样写:

Observable
    .Timer(DateTimeOffset.Now.AddDays(29.0))
    .Subscribe(x =>
    {
        /* 29 Days Later */
    });