那么说起定时执行任务,多数码农一定会知道timer,而且有各种说法。
c#中的三个timer类:
System.Timers.Timer:在一个固定时间间隔触发并执行code,这个类主要用于服务端或作为服务组件用在多线程环境中,它没有用户界面并且运行时不可见。//不推荐,在.NET Framework 5, .NET Core and ASP.NET Core中都已弃用
System.Threading.Timer:在一个线程池中固定时间间隔执行一个回调方法,这个回调方法在实例化时被定义 ,并且不能修改。跟System.Timers.Timerg一样主要用于服务端或作为服务组件用在多线程环境中,它没有用户界面并且运行时不可见。//推荐
System.Windows.Forms.Timer:是一上Windows Forms 的组件,在固定时间间隔触发一个事件并执行,这个组件没有用户界面并且是为单线程设计的.
System.Web.UI.Timer:是一个Asp.NET组件,可以在定期进行异步或同步web页面回发。
总之呢,先来对这三种Timer实战一次:
System.Timers.Timer,贴code:
public class TimerTest
{
private System.Timers.Timer timer = new Timer();
private DateTime dtSwitchJob = null;
public TimerTest()
{
timer.Interval = 1000;//每秒执行一次
timer.Elapsed += t_Elapsed;
}
public void Start()
{
timer.Enabled = true;
dtSwitchJob = DateTime.Now.AddMinutes(1);//一分钟后修改执行间隔
}
public void Stop()
{
timer.Enabled = false;
}
private void t_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime dtNow = DateTime.Now;
if (dtNow.Date == dtSwitchJob.Date && dtNow.Hour == dtSwitchJob.Hour && dtNow.Minute == dtSwitchJob.Minute)
{
timer.Interval = 60*1000;//一分钟后设定为每分钟执行一次
}
Console.WriteLine(DateTime.Now);
}
}System.Threading.Timer,贴code:
private static System.Threading.Timer timer = null; //new System.Threading.Timer(Run, null, , 2000);
public static void Run(object param)
{
Console.WriteLine("Running" + DateTime.Now);
timer.Change(10 * 1000, Timeout.Infinite);//每10秒执行一次guan
}
public TimerTest()
{
timer = new System.Threading.Timer(Run, null, 1000, 5000);//1秒后,每隔5秒钟执行一次
}
//下面是Timer带参数的例子,为了不误人子弟我直接粘官方了:
using System;
using System.Threading;
class TimerExample
{
static void Main()
{
//在回调函数中创建一个事件来标识超时数量的阀值
AutoResetEvent autoEvent = new AutoResetEvent(false);
StatusChecker statusChecker = new StatusChecker(10);
//为timer创建一个计时器的推断委托
TimerCallback tcb = statusChecker.CheckStatus;
//创建一个标识委托在1秒之后,每隔1/4秒就调用一次CheckStatus来计时器
Console.WriteLine("{0} Creating timer.\n", DateTime.Now.ToString("h:mm:ss.fff"));
Timer stateTimer = new Timer(tcb, autoEvent, 1000, 250);
//当autoEvent被标识,改变周期为每1/2分钟一次
autoEvent.WaitOne(5000, false);
stateTimer.Change(0, 500);
Console.WriteLine("\nChanging period.\n");
//当autoEvent第二次被标识时,释放timer
autoEvent.WaitOne(5000, false);
stateTimer.Dispose();
Console.WriteLine("\nDestroying timer.");
}
}
class StatusChecker
{
private int invokeCount;
private int maxCount;
public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}
//这个方法会被Timer委托调用
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.", DateTime.Now.ToString("h:mm:ss.fff"), (++invokeCount).ToString());
if(invokeCount == maxCount)
{
//重置counter并且给主线程一个信号
invokeCount = 0;
autoEvent.Set();
}
}
}
补充:
AutoResetEvent 允许线程通过发信号互相通信。通常,此通信涉及线程需要独占访问的资源。
线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程
通过调用 Set 发出资源可用的信号。
调用 Set 向 AutoResetEvent 发信号以释放等待线程。AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待,则状态将无限期地保持为终止状态。
可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false。
通俗的来讲只有等myResetEven.Set()成功运行后,myResetEven.WaitOne()才能够获得运行机会;Set是发信号,WaitOne是等待信号,只有发了信号,
等待的才会执行。如果不发的话,WaitOne后面的程序就永远不会执行
这段补充来自:http://www.cnblogs.com/lzjsky/archive/2011/07/11/2102794.html
System.Windows.Forms.Timer,贴code:
//在工具箱中拖了个timer过来.会生成下面的这部分code片段
#region 窗体设计部分的代码可不用看
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(646, 455);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Timer timer1;
}
#endregion
//要注意的是下面的这行事件绑定代码:
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//在初始化或Load事件,再或者在窗体中直接设置
timer1.Interval = 1000;//每秒执行一次
//下面就是你要执行的方法的主体部分
private void timer1_Tick(object sender, EventArgs e)
{
Console.WriteLine("我还会回来的!");
}本文参考:
官方对Timer的解释:https://msdn.microsoft.com/en-us/library/system.threading.timer.aspx
感觉帮助的讨论:http://stackoverflow.com/questions/1416803/system-timers-timer-vs-system-threading-timer
这位仁兄也有例子:http://www.cnblogs.com/Joetao/articles/2643378.html
原文:http://lybing.blog.51cto.com/3286625/1829194