c# 之 timer 實戰

分類:IT技術 時間:2016-10-12

那麽說起定時執行任務,多數碼農一定會知道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


Tags:

文章來源:


ads
ads

相關文章
ads

相關文章

ad