写服务时,都需要为定时器写不少的代码,感觉很麻烦,今天把这些代码封装一下,希望能简化一下这方面的工作,把精力都集中在功能上
本定时器组件,每次只启动一个服务实例进行处理,而不会同时多次执行服务代码。
下面是应用实例
从组件类派生一个子类,可以看到,需要写的代码很少 using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Threading; namespace BlueVision.SaYuan.WinService { public class TestService : ServiceTimerContorl { protected override void StartService() { //需要做的事情的代码 } protected override ServiceTimeConfig GetTimerConfig() { ServiceTimeConfig config = new ServiceTimeConfig(); // 如果该枚举是选择 Interval ,则表示,上述的 StartService 方法,将隔 config.ChkInterval 毫秒执行一次 config.TimerMode = TimerMode.Interval; config.ChkInterval = 100000; /// StartTime值为: /// /// TimerMode=TimerMode.Month "09|04:30" -表示每月9号的凌晨4点30分 /// TimerMode=TimerMode.Week "0|04:30" -表示每星期天的4点30分 /// TimerMode=TimerMode.Week "6|04:00" -表示每星期6的4点30分 /// TimerMode=TimerMode.Day "|04:00" -表示每天的4点00分 /// TimerMode=TimerMode.Date "08-10|04:00" -表示每年8月10号的4点00分执行一次 /// TimerMode=TimerMode.Year "246|04" -表示每年第246天的4点00分执行一次(可以不填写分钟默认为00) //如果是这样设置 则表示,每天的凌晨 4 点 00 执行一次 config.TimerMode = TimerMode.Day; config.StartTime = "|04"; //如果是这样设置 则表示,每个星期的星期四那天的凌晨 6 点 35 执行一次 config.TimerMode = TimerMode.Week; config.StartTime = "4|06:35"; //如果是这样设置 则表示,每个星期的星期天那天的凌晨 6 点 00 执行一次 config.TimerMode = TimerMode.Week; config.StartTime = "0|06"; //如果是这样设置 则表示,每个月的9号凌晨 6 点 28 执行一次 config.TimerMode = TimerMode.Month; config.StartTime = "09|06:28"; //如果是这样设置 则表示,每年8月10号的4点00分执行一次 config.TimerMode = TimerMode.Date; config.StartTime = "08-10|04:00"; //如果是这样设置 则表示,每年第246天的4点27分执行一次 config.TimerMode = TimerMode.Year; config.StartTime = "246|04:27"; return config; } /// /// 当服务出错时,处理 /// /// protected override void ServiceException(Exception ex) { //可以不实现 } } } //要执行代码,以下这样就可以了 TestService testService = new TestService(); testService.Start(); 以下是组件的源代码 using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Threading; namespace BlueVision.SaYuan.WinService { /// /// 服务定时器管理 /// public abstract class ServiceTimerControl { #region 私有成员 /// /// 定时器 /// private Timer SysTimer { get; set; } /// /// 是否启用定时器 /// private bool _EnabledTimer = true; /// /// 服务执行状态 /// private ServiceStatus _serviceStatus = ServiceStatus.Sleep; /// /// 时间计算类 /// private TimerControl _timerControl = null; /// /// 定时器配置 /// ServiceTimeConfig Config; #endregion #region 公共属性 /// /// 获取服务状态 /// public ServiceStatus ServiceStatus { get { return _serviceStatus; } } /// /// 计时模式 /// public TimerMode TimerMode { get { if ( Config == null ) Config = this.GetTimerConfig(); return Config.TimerMode; } } /// /// 计时配置 /// public string StartTime { get { return ( Config == null ) ? "" : Config.StartTime; } } /// /// 时间计算类 /// public TimerControl TimerControl { get { if ( Config == null ) Config = this.GetTimerConfig(); if ( _timerControl == null ) _timerControl = new TimerControl( this.Config.StartTime, this.Config.TimerMode ); return _timerControl; } } #endregion /// /// 停止 /// public void Stop() { _EnabledTimer = false; SysTimer.Change( Timeout.Infinite, Timeout.Infinite ); } /// /// 开始服务 /// public void Start() { _EnabledTimer = true; Config = this.GetTimerConfig(); SysTimer = new Timer( new TimerCallback( this.TimerProcess ), AppDomain.CurrentDomain, 0, this.Config.ChkInterval ); } /// /// 处理间隔服务 /// /// private void TimerProcess( object sender ) { if ( !_EnabledTimer ) return; bool TimeIsUp = true; if ( this.Config.TimerMode != TimerMode.Interval ) { // 如果定时方式不是定时轮询的话,就构造TimerControl类,该类用来计算每次执行完程序后 // 到下次执行服务时需要休眠的时间 try { _timerControl = new TimerControl( this.Config.StartTime, this.Config.TimerMode ); TimeIsUp = _timerControl.TimeIsUp; // 获取是否到了执行服务程序的时间了 } catch ( Exception ex ) { // 读取配置出错且TimerControl对象已不存在,则再抛出异常 // 如果上一次读取配置成功,那就就算这次的配置有问题,则也不会停止程序的运行,仍用上一次的数据做为参数 if ( _timerControl == null ) throw ex; } } try { if ( TimeIsUp )// 时间到了可以执行程序了 { // 服务运行了 _serviceStatus = ServiceStatus.Running; // 设置计时器,在无穷时间后再启用(实际上就是永远不启动计时器了--停止计时器计时) SysTimer.Change( Timeout.Infinite, this.Config.ChkInterval ); //开始处理服务 this.StartService(); } } catch ( Exception ex ) { this.ServiceException( ex ); } // 处理服务执行过程中出现的异常 finally { // 如果计时器不为空,则重新设置休眠的时间 if ( SysTimer != null ) { if ( this.Config.TimerMode == TimerMode.Interval )// 定时轮询设置 { // 重新启用计时器 SysTimer.Change( this.Config.ChkInterval, this.Config.ChkInterval ); } else// 定时设置 { // 用cft类计算下一次到期的时间 TimeSpan Interval = _timerControl.GetNextTimeUp(); // 重新启用计时器 SysTimer.Change( Interval, Interval ); } } _serviceStatus = ServiceStatus.Sleep; } } /// /// 开始服务 /// protected abstract void StartService(); /// /// 定时器初始化 /// /// /// /// protected abstract ServiceTimeConfig GetTimerConfig(); /// /// 系统服务错误 /// /// protected virtual void ServiceException( Exception ex ) { return; } } #region 定时器相关实体类 /// /// 服务定时器配置 /// public class ServiceTimeConfig { /// /// 轮询目录时间间隔(单位:毫秒) /// public int ChkInterval { get; set; } /// /// StartTime值为: /// /// TimerMode=TimerMode.Month "09|04:30" -表示每月9号的凌晨4点30分 /// TimerMode=TimerMode.Week "0|04:30" -表示每星期天的4点30分 /// TimerMode=TimerMode.Week "6|04:00" -表示每星期6的4点30分 /// TimerMode=TimerMode.Day "|04:00" -表示每天的4点00分 /// TimerMode=TimerMode.Date "08-10|04:00" -表示每年8月10号的4点00分执行一次 /// TimerMode=TimerMode.Year "246|04" -表示每年第246天的4点00分执行一次(可以不填写分钟默认为00) /// public string StartTime { get; set; } /// /// 服务器定时处理模型 /// public TimerMode TimerMode { get; set; } } /// /// 服务处理方法 /// public enum TimerMode { /// /// 轮询方式 /// Interval = 0, /// /// 一个月中某个天数的指定时间 /// Month = 1, /// /// 一周中的周几的指定时间 /// Week = 2, /// /// 一天中的指定时间 /// Day = 3, /// /// 一年中第几天的指定时间 /// Year = 4, /// /// 一年中的指定日期的指定时间 /// Date = 5, /// /// 未设置 /// NoSet } /// /// 服务处理方法 /// public enum ServiceStatus { /// /// 休眠中 /// Sleep = 0, /// /// 服务在执行过程中 /// Running = 1 } #endregion #region 定时服务休眠时间计算类 /// /// 定时服务休眠时间计算类 /// public class TimerControl { #region 私有成员 /// /// 间隔单位 /// private TimerMode type; /// /// 月份 /// private int Month; /// /// 天 /// private int Day; /// /// 小时 /// private int Hour; /// /// 分钟 /// private int Minute = 0; #endregion #region 公共成员方法 /// /// StartTime值为: /// /// TimerMode=TimerMode.Month "09|04:30" -表示每月9号的凌晨4点30分 /// TimerMode=TimerMode.Week "0|04:30" -表示每星期天的4点30分 /// TimerMode=TimerMode.Week "6|04:00" -表示每星期6的4点30分 /// TimerMode=TimerMode.Day "|04:00" -表示每天的4点00分 /// TimerMode=TimerMode.Date "08-10|04:00" -表示每年8月10号的4点00分执行一次 /// TimerMode=TimerMode.Year "246|04" -表示每年第246天的4点00分执行一次(可以不填写分钟默认为00) /// /// /// public TimerControl( string StartTime, TimerMode timeMode ) { //Regex regEx = new Regex( @"(?[MWDY])(?\d+)?\|(?\d+):?(?[0 -5]\d?)?", RegexOptions.Compiled | RegexOptions.IgnoreCase ); Regex regEx = new Regex( @"^(?:(?[0]?\d|1[0-2])-)?(?\d{1,3})?\|(?[01]?\d|2[0-3])(?::(?[0-5]\d?))?$", RegexOptions.Compiled | RegexOptions.IgnoreCase ); this.type = timeMode; Match m = regEx.Match( StartTime ); if ( m.Success ) { if ( String.IsNullOrEmpty( m.Groups["Month"].Value ) && this.type == TimerMode.Date ) throw new Exception( "定时器时间配置异常!" ); if ( !String.IsNullOrEmpty( m.Groups["Month"].Value ) ) this.Month = Convert.ToInt32( m.Groups["Month"].Value ); if ( !String.IsNullOrEmpty( m.Groups["Days"].Value ) ) this.Day = Convert.ToInt32( m.Groups["Days"].Value ); this.Hour = Convert.ToInt32( m.Groups["Hour"].Value ); if ( !String.IsNullOrEmpty( m.Groups["Minute"].Value ) ) this.Minute = Convert.ToInt32( m.Groups["Minute"].Value ); } else throw new Exception( "定时器时间配置异常!" ); } /// /// 判断时间是否到了 /// /// public bool TimeIsUp { get { DateTime dt = DateTime.Now; switch ( type ) { case TimerMode.Day: return ( dt.Hour == this.Hour && dt.Minute == this.Minute ); case TimerMode.Month: return ( dt.Day == this.Day && dt.Hour == this.Hour && dt.Minute == this.Minute ); case TimerMode.Week: return ( ( ( int )dt.DayOfWeek ) == this.Day && dt.Hour == this.Hour && dt.Minute == this.Minute ); case TimerMode.Date: return ( dt.Month == this.Month && dt.Day == this.Day && dt.Hour == this.Hour && dt.Minute == this.Minute ); case TimerMode.Year: return ( dt.DayOfYear == this.Day && dt.Hour == this.Hour && dt.Minute == this.Minute ); } return false; } } /// /// 从现在起到下次时间到还有多少时间 /// /// public TimeSpan GetNextTimeUp() { ///目标时间 DateTime _NextDateTime = this.GetNextDateTime(); // 保存下一次要执行的时间 TimeSpan NextCrtFileTime = _NextDateTime - DateTime.Now; if ( ( int )NextCrtFileTime.TotalMilliseconds > int.MaxValue ) // 如果要休眠的时间间隔超过int类型可以表示的毫秒时,先休眠到int.MaxValue,然后再次休眠 NextCrtFileTime = new TimeSpan( int.MaxValue ); return NextCrtFileTime; } /// /// 获取下一次指定配置的时间是多少 /// /// public DateTime GetNextDateTime() { DateTime dt = DateTime.Now; DateTime now, target; switch ( this.type ) { case TimerMode.Day: #region 每天指定某时执行一次 now = new DateTime( 1, 1, 1, dt.Hour, dt.Minute, 0 ); target = new DateTime( 1, 1, 1, this.Hour, this.Minute, 0 ); if ( now.Ticks >= target.Ticks ) dt = dt.AddDays( 1.0 ); //如果当前时间小于指定时刻,则不需要加天 dt = new DateTime( dt.Year, dt.Month, dt.Day, this.Hour, this.Minute, 0 ); #endregion break; case TimerMode.Month: #region 每月指定某天某时执行一次 now = new DateTime( 1, 1, dt.Day, dt.Hour, dt.Minute, 0 ); target = new DateTime( 1, 1, this.Day, this.Hour, this.Minute, 0 ); if ( now.Ticks >= target.Ticks ) dt = dt.AddMonths( 1 ); dt = new DateTime( dt.Year, dt.Month, this.Day, this.Hour, this.Minute, 0 ); #endregion break; case TimerMode.Week: #region 每星期指定星期某时执行一次 int dow = ( int )dt.DayOfWeek; now = new DateTime( 1, 1, dow + 1, dt.Hour, dt.Minute, 0 ); target = new DateTime( 1, 1, this.Day + 1, this.Hour, this.Minute, 0 ); if ( now.Ticks >= target.Ticks ) dt = dt.AddDays( this.Day - dow + 7 ); else dt = dt.AddDays( this.Day - dow ); dt = new DateTime( dt.Year, dt.Month, dt.Day, this.Hour, this.Minute, 0 ); #endregion break; case TimerMode.Date: #region 每年指定某月某日某时执行一次 now = new DateTime( 1, dt.Month, dt.Day, dt.Hour, dt.Minute, 0 ); target = new DateTime( 1, this.Month, this.Day, this.Hour, this.Minute, 0 ); if ( now.Ticks >= target.Ticks ) dt = dt.AddYears( 1 ); dt = new DateTime( dt.Year, this.Month, this.Day, this.Hour, this.Minute, 0 ); #endregion break; case TimerMode.Year: #region 每年指定第N天某时执行一次 now = new DateTime( 1, 1, 1, dt.Hour, dt.Minute, 0 ); target = new DateTime( 1, 1, 1, this.Hour, this.Minute, 0 ); if ( dt.DayOfYear > this.Day || dt.DayOfYear == this.Day && now.Ticks >= target.Ticks ) dt = dt.AddYears( 1 ); dt = dt.AddDays( this.Day - dt.DayOfYear ); dt = new DateTime( dt.Year, dt.Month, dt.Day, this.Hour, this.Minute, 0 ); #endregion break; default: throw new Exception( "定时器时间配置异常!" ); } return dt; } #endregion } #endregion }
发表评论
-
(转)C#数据库连接字符串
2012-07-06 09:52 700本文介绍C#数据库 ... -
'make menuconfig' requires the ncurses libraries.
2012-07-06 09:46 955过去的4年(或者六 ... -
关于Flex4工程和 Alternativa3D 7.5.1的疑问
2012-07-02 13:08 578原文:http://bbs.9ria.com/thread ... -
将flex组件添加到papervision3d
2012-07-02 13:08 400上一篇文章介绍了如何将papervision3d作为组件添 ... -
Flex 4架构的组件开发
2012-07-02 13:08 574Flex 4架构的组件开发 作者:Michael Labr ... -
Flex style - CSS 的使用
2012-07-02 13:08 528Dan Orlando, 软件架 ... -
flex 绑定资源
2012-07-02 13:08 645Adobe Flex supports several i ... -
[转]Flex中[Bindable]的用法
2012-07-01 10:39 751什么是元数据(metadata):[Bindable]大 ... -
flex3:drag-drop全攻略(二)
2012-07-01 10:38 711这里写四个实例:1,List->List 2, ... -
flex4+servlet 实现文件上传功能
2012-07-01 10:38 595最近老是被问到flex的上传问题怎么解决,今天就贴出web ... -
flex图表
2012-07-01 10:38 663flex 可视化组件中 ... -
Flex 文件上传导入组件
2012-06-30 17:03 664Flex 文件上传导入组件 2010年09月13日 上文 ... -
Java Server Push To Flex (ServerPush)
2012-06-30 17:02 726Java Server Push To Flex (Serve ... -
Flex通过javascript读写cookie
2012-06-30 17:02 682Flex通过javascript读写cookie 2010年 ... -
全面认识Flex弹出窗口用法
2012-06-30 17:02 567全面认识Flex弹出窗口用 ...
相关推荐
定时器使用定时器使用定时器使用定时器使用定时器使用定时器使用定时器使用定时器使用定时器使用
vs c# 闹钟 闹铃 组件 dll 定时器 有源代码
C#多线程实现定时器
MmTimer 是一个多媒体定时器的C#简单封装。 使用这个定时器,你可以得到1ms精度的单次延时或周期定时。最初是想用来做播放midi文件的时钟,当然你也可以用它来做任何它能做到的事情。
C# 定时器 计时器 的使用详解
C#中定时器停止问题,停止定时器必须要用Stop方法才行,不然依然会工作的。
c#高精度定时器源码,可以直接运行,多媒体定时器,解决c#自身定时器不准确的问题
比较了C#中的各种定时器,不同定时器的应用场景,并附有代码示例。
MCAD-MCSD制胜宝典—用Visual Basic .NET和Visual C#.NET开发XML Web服务与服务器组件。
C# socket(udp),设置定时器,定时发送数据
C#定时器的三种实现方法(System.Timers.Timer、System.Windows.Forms.Timer、System.Threading.Timer)
实用结合C#反射实现动态定时器定时任务工具,可结合XML配置文档,实现独立动态的定时配置;用于定时任务执行、消息推送、WebService任务等;附件为程序源码。工具历经多项目验证,不足之处;欢迎交流指正!
提供任务多样化的定时功能. 详细说明.参见: http://blog.csdn.net/linux7985/article/details/9301163
C#定时器的用法,简单易懂,值得拥有。赶紧下载吧
本文详细论述了C#中三种定时器的实现,程序开发中常用到定时器。
C#调用采用C++/CLR封装的多媒体定时器的例子及封装库文件。可用Winform和WPF程序中。经过测试可用。
C# 开发全套31个UI组件Winform 开源共享 开源 控件
C#组件开发简易教程. 用多个实例简明讲述C#组件开发的方法和过程。
C#.net 定时器, Timer, 定时任务
本实例来自《C#编程宝典》中的一例,保证是原完整源代码。主要介绍使用TIME控件实现定时器,涉及到系统时间的获取,时间设置等等,详细自己自吧,下载分是高了点,请谅解!