您的位置:首页 > 编程语言 > C#

c# 之 timer 实战

2016-07-23 20:55 387 查看
那么说起定时执行任务,多数码农一定会知道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 发出资源可用的信号。
调用 SetAutoResetEvent 发信号以释放等待线程。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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: