C#的四種Timer介紹


 

一.Timer的幾個類別

  1.System.Threading.Timer

  2.System.Timers.Timer

  3.System.Windows.Forms.Timer

  4.System.Windows.Threading.DispatcherTimer

二.System.Threading.Timer

  他的源代碼里是這樣寫的:

public sealed class Timer : MarshalByRefObject, IDisposable
{
    // Fields
    private TimerHolder m_timer;
    private const uint MAX_SUPPORTED_TIMEOUT = 0xfffffffe;

    // Methods
    [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical]
    public Timer(TimerCallback callback);
    [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical, __DynamicallyInvokable]
    public Timer(TimerCallback callback, object state, int dueTime, int period);
    [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical]
    public Timer(TimerCallback callback, object state, long dueTime, long period);
    [MethodImpl(MethodImplOptions.NoInlining), SecuritySafeCritical, __DynamicallyInvokable]
    public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);
    [MethodImpl(MethodImplOptions.NoInlining), CLSCompliant(false), SecuritySafeCritical]
    public Timer(TimerCallback callback, object state, uint dueTime, uint period);
    [__DynamicallyInvokable]
    public bool Change(int dueTime, int period);
    public bool Change(long dueTime, long period);
    [__DynamicallyInvokable]
    public bool Change(TimeSpan dueTime, TimeSpan period);
    [CLSCompliant(false)]
    public bool Change(uint dueTime, uint period);
    [__DynamicallyInvokable]
    public void Dispose();
    public bool Dispose(WaitHandle notifyObject);
    internal void KeepRootedWhileScheduled();
    [SecurityCritical]
    internal static void Pause();
    [SecurityCritical]
    internal static void Resume();
    [SecurityCritical]
    private void TimerSetup(TimerCallback callback, object state, uint dueTime, uint period, ref StackCrawlMark stackMark);
}

   主要有四個參數。

  CallBack,一個返回值為void,參數為object的委托,也是計時器執行的方法。

    state,計時器執行方法的的參數。

   dueTime,調用 callback 之前延遲的時間量(以毫秒為單位)。

   period,調用 callback 的時間間隔。

  例:System.Threading.Timer tm=new System.Threading.Timer(Tick_tick,null,10000,20000);//10秒后開始計時,20秒后調用Tick_tick事件。

  特點:多線程計時器,精確,而且可擴展性強。

三.System.Timers.Timer

  在Reflector里反射出來的源代碼:

 public Timer();
    public Timer(double interval);
    public void BeginInit();
    public void Close();
    protected override void Dispose(bool disposing);
    public void EndInit();
    [SuppressUnmanagedCodeSecurity, DllImport("kernel32.dll")]
    internal static extern void GetSystemTimeAsFileTime(ref FILE_TIME lpSystemTimeAsFileTime);
    private void MyTimerCallback(object state);
    public void Start();
    public void Stop();
    private void UpdateTimer();

    // Properties
    [Category("Behavior"), TimersDescription("TimerAutoReset"), DefaultValue(true)]
    public bool AutoReset { get; set; }
    [Category("Behavior"), TimersDescription("TimerEnabled"), DefaultValue(false)]
    public bool Enabled { get; set; }
    [Category("Behavior"), TimersDescription("TimerInterval"), DefaultValue((double) 100.0), SettingsBindable(true)]
    public double Interval { get; set; }
    public override ISite Site { get; set; }
    [Browsable(false), DefaultValue((string) null), TimersDescription("TimerSynchronizingObject")]
    public ISynchronizeInvoke SynchronizingObject { get; set; }

  BeginInit(),初始化。

  AutoReset,只執行一次或重復執行。

  enabled,獲取或設置一個值,該值指示 Timer 是否應引發 Elapsed 事件。

  Interval,相應間隔時間。

  Elapsed綁定響應事件。

  例:

 public MainWindow()
        {
            InitializeComponent();
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.AutoReset = true;
            timer.Enabled = true;
            timer.Interval=10000;
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            MessageBox.Show("響應事件");
        }

   特點:相對System.Threading.Timer進行了簡單包裝。多線程計時器

  實現了Component,所以可以在設計器顯示。代替Change方法的一個Interval屬性代替callback委托的一個Elapsed事件啟動和停止timer的Enabled屬性,默認是false。

  為了避免Enabled造成混亂,提供了Start和Stop方法。是否在每次指定的間隔結束時引發Elapsed時間,還是僅間隔第一次結束后運行的AutoReset屬性。

四.差異

  (1)上述兩個Timer都是多線程計時器。Timer每到間隔時間后就會激發響應事件,因此要申請線程來執行對應的響應函數,Timer將獲取線程的工作都交給了線程池來管理,

  每到一定的時間后它就去告訴線程池:“我現在激發了個事件要運行對應的響應函數,麻煩你給我向操作系統要個線程,申請交給你了,線程分配下來了你就運行我給你的響應函數,

  沒分配下來先讓響應函數在這兒排隊(操作系統線程等待隊列)”,消息已經傳遞給線程池了,Timer也就不管了,因為它還有其他的事要做(每隔一段時間它又要激發事件),

  至於提交的請求什么時候能夠得到滿足,要看線程池當前的狀態,如果線程滿了就排隊,在有空線程時就會響應函數。否則就直接響應。

  (2)而下述兩個是單線程計時器,其工作機制也和上面不同。計時器使用消息循環機制來取代線程池產生消息的機制。

  這意味着Tick事件總是在創建timer的那個線程上執行,同時也意味着如果上一個Tick消息還未被處理,即使時間超過了間隔時間,在消息循環中也只存在一個Tick消息。

  下面是它們的優點:

  你可以忘記線程安全。一個Tick事件在前一個Tick事件被處理完畢前不會被觸發。你可以直接在Tick事件處理代碼中更新控件,不需要調用Control.Invoke或Dispatcher.Invoke.

五.System.Windows.Forms.Timer

  專門適用於WindowForm,單線程使用。由於單線程計時器基於Windows消息循環,應用程序會同步的處理計時器的消息。UI界面會相對響應速度很慢。

  WinForm不常用,就不寫了。

六.System.Windows.Threading.DispatcherTimer

  Reflector的源代碼方法

   public DispatcherTimer();
    public DispatcherTimer(DispatcherPriority priority);
    public DispatcherTimer(DispatcherPriority priority, Dispatcher dispatcher);
    public DispatcherTimer(TimeSpan interval, DispatcherPriority priority, EventHandler callback, Dispatcher dispatcher);
    private object FireTick(object unused);
    private void Initialize(Dispatcher dispatcher, DispatcherPriority priority, TimeSpan interval);
    internal void Promote();
    private void Restart();
    public void Start();
    public void Stop();

    // Properties
    public Dispatcher Dispatcher { get; }
    public TimeSpan Interval { get; set; }
    public bool IsEnabled { get; set; }
    public object Tag { get; set; }
}

  類似於System.Threading.Timer

  例:

  public MainWindow()
        {
            InitializeComponent();
            
             Timer.Interval = TimeSpan.FromSeconds(1000);
             Timer.IsEnabled = true;
             Timer.Tick += Timer_Tick;

        }

        void Timer_Tick(object sender, EventArgs e)
        {
            throw new NotImplementedException();
        }
      private  DispatcherTimer Timer;

 

六.寫在最后

  新手學習總結,輕噴輕拍。寫的不一定全對,有錯歡迎糾正。

  文中有多處借鑒自:iloli的專欄 

  

 

  

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM