那么说起定时执行任务,多数码农一定会知道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