public static void Test() { Console.WriteLine("+++++++++++++++++PlanTimeTest+++++++++++++++++"); PlanTime time = new PlanTime(2013, 11, 12, 4, 26, 12); { Console.WriteLine("-----------------OneOff-------------------"); PlanTime time2 = PlanTime.Parse("2013-01-12 02:03:40"); Console.WriteLine("String:{0}", time2.ToString()); Console.WriteLine("ToDateTime:{0}", time2.ToDateTime()); Console.WriteLine("GetNextTime:{0}", time2.GetNextTime()); } { Console.WriteLine("-----------------Daily-------------------"); PlanTime time2 = PlanTime.Parse("03:16:05"); Console.WriteLine("String:{0}", time2.ToString()); Console.WriteLine("ToDateTime:{0}", time2.ToDateTime()); Console.WriteLine("GetNextTime:{0}", time2.GetNextTime()); } { Console.WriteLine("-----------------Weekly-------------------"); PlanTime time2 = PlanTime.Parse("23:58:05 Sunday"); Console.WriteLine("String:{0}", time2.ToString()); Console.WriteLine("ToDateTime:{0}", time2.ToDateTime()); Console.WriteLine("GetNextTime:{0}", time2.GetNextTime()); } }
/// <summary> /// /// </summary> /// <param name="state"></param> private void PlanTimerCallBack(Object state) { Boolean needRepeat = false; m_RaiseTimer.Change(Timeout.Infinite, Timeout.Infinite); try { //过滤那些应为触发时间过长,而无法使用线程时钟的时间间隔,转而使用1天的间隔所触发事件 if (m_Time.ToDateTime().Date == DateTime.Now.Date) { try { RaiseReminding(); } catch { } AddRemindedTime(); Int32 newValue = 0; needRepeat = m_RepeatThreshold.TryIncrement(out newValue); } else { return; } } catch (Exception ex) { Console.WriteLine(String.Format("Plan.Reminding error, {0}", ex.Message)); } finally { Thread.Sleep(TimeSpanEpsilon);//由于线程时钟含有几百毫秒的误差,此处的Sleep用于调整可能出现的误差问题 m_RaiseTimer.Change(GetNextRaisePeriod(needRepeat), RepeatInterval); } }
/// <summary> /// 创建时间段计划对象 /// </summary> /// <param name="id"></param> /// <param name="beginYear"></param> /// <param name="beginMonth"></param> /// <param name="beginDay"></param> /// <param name="beginHour"></param> /// <param name="beginMinute"></param> /// <param name="beginSecond"></param> /// <param name="beginDayOfWeek"></param> /// <param name="endYear"></param> /// <param name="endMonth"></param> /// <param name="endDay"></param> /// <param name="endHour"></param> /// <param name="endMinute"></param> /// <param name="endSecond"></param> /// <param name="endDayOfWeek"></param> internal PlanPeriod(String id, Nullable <Int32> beginYear, Nullable <Int32> beginMonth, Nullable <Int32> beginDay, Int32 beginHour, Int32 beginMinute, Int32 beginSecond, Nullable <DayOfWeek> beginDayOfWeek, Nullable <Int32> endYear, Nullable <Int32> endMonth, Nullable <Int32> endDay, Int32 endHour, Int32 endMinute, Int32 endSecond, Nullable <DayOfWeek> endDayOfWeek) { this.Tag = null; this.Id = id; m_BeginTime = new PlanTime(beginYear, beginMonth, beginDay, beginHour, beginMinute, beginSecond, beginDayOfWeek); m_EndTime = new PlanTime(endYear, endMonth, endDay, endHour, endMinute, endSecond, endDayOfWeek); m_Begun = false; if (m_BeginTime.Type != m_EndTime.Type) { throw new ArgumentException("PlanPeriod constructor error, the begin time type must be the same as the end time."); } if (m_BeginTime.ToDateTime() >= m_EndTime.ToDateTime()) { throw new ArgumentException("PlanPeriod constructor error, the begin time must be less than the end time."); } lock (typeof(PlanPeriod)) { PlanPeriod.PlanPeriods.Add(this); } this.Enabled = true; }
/// <summary> /// 获取下次触发事件的时间间隔 /// </summary> /// <returns>返回时间间隔</returns> private TimeSpan GetNextRaisePeriod() { DateTime begin = m_BeginTime.ToDateTime(); DateTime beginNext = m_BeginTime.GetNextTime(); DateTime end = m_EndTime.ToDateTime(); DateTime endNext = m_EndTime.GetNextTime(); DateTime now = DateTime.Now; TimeSpan result; if (m_Begun == false) { //此次的时间段已过期,需要使用下次的时间段 if (now > end) { //Console.WriteLine("Begun false, now > end. {0} > {1}", now, end); result = beginNext - now; } //此次的时间段尚未抵达 else if (now < begin) { //Console.WriteLine("Begun false, now < begin. {0} < {1}", now, begin); result = begin - now; } //在时间段内 else { //Console.WriteLine("Begun false, in range. {0} in {1}/{2}", now, begin, end); result = TimeSpan.FromMilliseconds(100);//立即触发 } } else { //已结束 if (now >= end) { //Console.WriteLine("Begun true, now >= end. {0} >= {1}", now, end); result = TimeSpan.FromMilliseconds(100);//立即触发 } //尚未开始,但是标志位已不正确 else if (now < begin) { //开始重置标记为 //Console.WriteLine("PlanPeriod begun flag error, reset flag now."); m_Begun = false; result = begin - now; } //在时间段内 else { //Console.WriteLine("Begun true, in range. {0} in {1}/{2}", now, begin, end); result = end - now; } } //如果时间间隔过长则使用一个简短的时间来做校正 if (result > TimeSpan.FromDays(10)) { return(TimeSpan.FromDays(1)); } else if (result < TimeSpan.FromMilliseconds(100)) { return(TimeSpan.FromMilliseconds(100)); } else { return(result); } }