码迷,mamicode.com
首页 > Windows程序 > 详细

c# 之 timer 实战

时间:2016-07-24 07:10:31      阅读:2277      评论:0      收藏:0      [点我收藏+]

标签:c#   线程   thread   timer   定时任务   

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

c# 之 timer 实战

标签:c#   线程   thread   timer   定时任务   

原文地址:http://lybing.blog.51cto.com/3286625/1829194

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!