Windows 服务中使用 Timer 控件时,Tick 事件不命中问题的解决
来源:互联网 发布:图片标注软件 编辑:程序博客网 时间:2024/06/10 03:59
Windows 服务中使用 Timer 控件时,Tick 事件不命中问题的解决
首先我们要分清一下两个 Timer 类,
System.Timers.Timer
System.Windows.Forms.Timer
估计现在大多数人都能明白问题产生的原因了吧!
其中在工具箱中默认存在的那个 Timer 控件,引用的是
System.Windows.Forms.Timer 类。
如果在写windows 服务时,使用的是在工具箱中添加的 Timer 控件,
那你就中奖了!(Tick 事件永远不会不命中。任凭你怎么调试,
它是不报异常并且也能编译通过)
现在就把windows 服务中的 Timer 改成 System.Timers.Timer 类吧!
需要注意的是两个类的“命中事件”是不一样的。
System.Timers.Timer.Elapsed
System.Windows.Forms.Tick
到这里,Tick 事件不命中问题的解决了。
下面是封装定时调用的一个组件类的代码
相信我们经常会遇到这样一种需求,就是“定时调用”而不是“间隔调用”
想设定一个或多个时间,每天定时执行相关代码。
下面我封装了一个支持“定时调用"和"间隔调用"的组件。
代码放到下面了。
注意:如果开启定时调用,则间隔调用将不起作用
-----------------------------------------------------------
-- WinServiceTimer.cs 文件
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Timers;
using Tt.WinService.Bll;
namespace Tt.WinService.ExpressTrack
{
/// <summary>
/// Win 服务中使用 timer 组件
/// 由于使用“工具箱”中的 Timer 在 Win 服务程序中不会命中,
/// 故写一个 在 win 服务中的 Timer 组件
/// </summary>
public partial class WinServiceTimer : Component
{
public WinServiceTimer()
{
InitializeComponent();
InitTimer();
}
public WinServiceTimer(IContainer container)
{
container.Add(this);
InitializeComponent();
InitTimer();
}
#region 事件
public delegate void TimerTickHandler(object sender, WinServiceTimerEventAgrs e);
/// <summary>
/// 当Timer 计时器时间到达时发生
/// </summary>
public event TimerTickHandler OnTimerTick;
#endregion
#region 变量
System.Timers.Timer m_timer = new System.Timers.Timer();
/// <summary>
/// 组件被触发的时间点集合
/// </summary>
private Timer[] m_invokeTime = null;
/// <summary>
/// 调用时间间隔
/// </summary>
private int m_invokeInterval = 30;
/// <summary>
/// 是否启用定时调用
/// </summary>
private bool m_EnableTimed = false;
#endregion
#region 控制timer组件属性
/// <summary>
/// 组件调用时间间隔(以‘分’为单位,取值 30-240)
/// </summary>
[Description("组件调用时间间隔(以‘分’为单位,取值 30-240)")]
public int Interval
{
set
{
if (value < 30 || value > 240)
throw new Exception("Interval 取值范围在 30-240 之间");
m_invokeInterval = value;
this.m_timer.Interval = m_invokeInterval * 60000;
}
get
{
return m_invokeInterval;
}
}
/// <summary>
/// 设置定时调用时间,同时需要设置 EnableTimed 为 true
/// </summary>
[Description("设置定时调用时间,同时需要设置 EnableTimed 为 true")]
public Timer[] InvokeTime
{
set
{
if (value != null && value.Length > 0)
{
this.EnableTimed = true;
}
m_invokeTime = value;
}
get
{
return m_invokeTime;
}
}
/// <summary>
/// 是否启用定时调用
/// </summary>
[DefaultValue(false)]
[Description("是否启用定时调用")]
public bool EnableTimed
{
set
{
//如果是定时调用,需要设置 timer 为 1 分钟调用一次
if (value)
{
this.m_timer.Interval = 60 * 1000;
}
else
{
this.m_timer.Interval = this.m_invokeInterval;
}
m_EnableTimed = value;
}
get
{
return m_EnableTimed;
}
}
/// <summary>
/// 获取或设置一个值,该值指示 System.Timers.Timer 是否应引发 System.Timers.Timer.Elapsed 事件。
/// </summary>
[Description("获取或设置一个值,该值指示 System.Timers.Timer 是否应引发 System.Timers.Timer.Elapsed 事件。")]
public bool Enabled
{
set
{
this.m_timer.Enabled = value;
}
get
{
return this.m_timer.Enabled;
}
}
#endregion
#region 控制定时器
/// <summary>
/// 获取调用时间的字符串表示形式
/// </summary>
/// <returns></returns>
public string GetInvokeTimeToString()
{
if (this.InvokeTime.IsNullOrDbNull())
return string.Empty;
string str = string.Empty;
InvokeTime.All(o =>
{
if (str.IsNullOrEmpty())
str += string.Format("{0}:{1}", o.Hour, o.Minute);
else
str += string.Format(",{0}:{1}", o.Hour, o.Minute);
return true;
});
return str;
}
#endregion
/// <summary>
/// 初始化调用时间
/// </summary>
private void InitTimer()
{
//设置timer 调用时间 30 分钟
this.m_timer.Interval = 30 * 60000;
}
/// <summary>
/// 通过将 System.Timers.Timer.Enabled 设置为 true 开始引发 System.Timers.Timer.Elapsed
/// 事件。
/// </summary>
public void Start()
{
this.m_timer.Elapsed += new ElapsedEventHandler(m_timer_Elapsed);
this.m_timer.Start();
}
/// <summary>
/// 通过将 System.Timers.Timer.Enabled 设置为 false 停止引发 System.Timers.Timer.Elapsed
/// 事件。
/// </summary>
public void Stop()
{
this.m_timer.Stop();
}
/// <summary>
/// 到达间隔时间时发生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void m_timer_Elapsed(object sender, ElapsedEventArgs e)
{
WinServiceTimerEventAgrs agrs = new WinServiceTimerEventAgrs();
agrs.EnableTimed = this.EnableTimed;
//定时调用
if (this.EnableTimed)
{
if (this.m_invokeTime.IsNullOrDbNull())
return;
DateTime currTime = DateTime.Now;
foreach (Timer time in m_invokeTime)
{
if (currTime.Hour == time.Hour && currTime.Minute == time.Minute)
{
//定时调用
if (OnTimerTick != null)
{
agrs.Time = time;
agrs.InvokeTime = currTime;
OnTimerTick(this, agrs);
}
}
}
return;
}
//普通间隔调用
if (OnTimerTick != null)
{
agrs.InvokeTime = DateTime.Now;
OnTimerTick(this, agrs);
}
}
}
/// <summary>
/// win 服务事件参数
/// </summary>
public class WinServiceTimerEventAgrs:EventArgs
{
/// <summary>
/// 定时调用的时间
/// </summary>
public Tt.WinService.ExpressTrack.Timer Time{ set;get; }
/// <summary>
/// 是否启用定时调用
/// </summary>
public bool EnableTimed { set; get; }
/// <summary>
/// 调用时间
/// </summary>
public DateTime InvokeTime { set; get; }
}
}
-----------------------------------------------------------
-- Timer.cs 文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Tt.WinService.ExpressTrack
{
/// <summary>
/// 定时器
/// </summary>
public class Timer
{
private int m_hour = 1;
private int m_minute = 0;
/// <summary>
/// 小时部分(1-23H)
/// </summary>
public int Hour
{
set
{
if (value < 1 || value > 23)
throw new Exception("Hour 取值范围在 1-23H 之间");
m_hour = value;
}
get { return m_hour; }
}
/// <summary>
/// 分钟部分(0-59)
/// </summary>
public int Minute
{
set
{
if (value < 0 || value > 59)
throw new Exception("Minute 取值范围在 0-59s 之间");
m_minute = value;
}
get { return m_minute; }
}
}
}
---------------------------------------------
转载请保留:http://write.blog.csdn.net/postedit/7565793
- Windows 服务中使用 Timer 控件时,Tick 事件不命中问题的解决
- Timer 控件中的Elapsed事件与tick事件的区别
- Windows服务中Timer组件Tick无法触发解决方法
- [VB.NET]利用Timer控件的Tick()事件在自定义控件上绘制动画!
- C#windows服务中的Timer控件的使用
- 2011-05-12 09:08 Windows服务中Timer组件Tick无法触发解决方法
- C# windows服务:C#windows服务中的Timer控件的使用
- 解决使用工具栏组件时控件焦点事件的问题
- windows服务中的定时器timer的使用
- ArcMap Add-in插件开发中解决VS调试时断点不会命中的问题
- ArcMap Add-in插件开发中解决VS调试时断点不会命中的问题
- ArcMap Add-in插件开发中解决VS调试时断点不会命中的问题
- 如何手工创建Timer控件,并且在Timer控件的事件中控制窗体控件
- Windows服务中Timer组件
- Windows服务中Timer组件
- 关于在自定义控件中事件不响应的问题
- 关于在自定义控件中事件不响应的问题
- UpdatePanel控件中使用GridView时,RowCommand事件执行删除后,GridView不刷新问题。
- Android GLSurfaceView.Renderer
- 第十三周实验报告(一)
- Jquery实现checkbox name是数组的情况下的全选/反选的2种写法
- 程序性能分析
- 程序员指南----速成篇
- Windows 服务中使用 Timer 控件时,Tick 事件不命中问题的解决
- Project Server 2010安装部署手册(1.5版)
- C#读取注册表,C#创建任务计划
- Spring2.5.6+Hibernate3.4+Struts2 2.1.6 +JPA集成
- Tomcat:Exception loading sessions from persistent storage
- ClientResponse .class与String.class区别
- 打印各种情况
- 关于构造函数 和 析构函数 能否抛出异常的讨论
- Spring3 MVC详解二