使用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
答案 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 */
});