C#-Forms.Timer、Timers.Timer、Threading.Timer的比較和使用


在.NET Framework里面提供了三種Timer

① System.Windows.Forms.Timer

② System.Timers.Timer

③ System.Threading.Timer

 

一、System.Windows.Forms.Timer

1、基於Windows消息循環,用事件方式觸發,在界面線程執行;是使用得比較多的Timer,Timer Start之后定時(按設定的Interval)調用掛接在Tick事件上的EvnetHandler。在這種Timer的EventHandler中可 以直接獲取和修改UI元素而不會出現問題--因為這種Timer實際上就是在UI線程自身上進行調用的。

2、它是一個基於Form的計時器
3、創建之后,你可以使用Interval設置Tick之間的跨度,用委托(delegate)hook Tick事件
4、調用Start和Stop方法,開始和停止
5、完全基於UI線程,因此部分UI相關的操作會在這個計時器內進行
6、長時間的UI操作可能導致部分Tick丟失

 


using System.Windows.Forms.Timer;
實現按用戶定義的時間間隔引發事件的計時器。此計時器最宜用於 Windows 窗體應用程序中,並且必須在窗口中使用。

這個類在Windows應用程序中使用,用來定期把WM_TIMER消息放到程序的消息隊列中。當程序從隊列中獲取消息后,它會在主用戶接口線程中同步處理,這對Windows應用程序來說非常重要。精度限定:55ms(引用自圖書《C#圖解教程(第四版)》439頁)

定時器任務執行時間比較長時,不建議使用Forms.Timer,會出現界面假死現象,建議使用Timers.Timer,不會界面假死,並且精度更高!

示例程序:(解釋Forms.Timer和Winform的窗體共用一個線程,現象:界面假死)
1、Winform窗體控件布局

 

2.源代碼

using System;
using System.Threading;
using System.Windows.Forms;

namespace Windows.Forms.Timer
{
public partial class Form1 : Form
{
int num = 0;
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}

private void button2_Click(object sender, EventArgs e)
{
timer1.Stop();
}

private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = (++num).ToString();
Thread.Sleep(3000);
}
}
}
3.執行效果

點擊Start按鈕后,界面假死3秒后,才可以移動窗體或點擊控件按鈕。

二、System.Timers.Timer

1. 用的不是Tick事件,而是Elapsed事件
2. 和System.Windows.Forms.Timer一樣,用Start和Stop方法
3. AutoReset屬性決定計時器是不是要發起一次事件然后停止,還是進入開始/等待的循環。System.Windows.Forms.Timer沒有這個屬性
4. 設置對於UI控件的同步對象(synchronizing object),對控件的UI線程發起事件


using System.Timers.Timer;
在應用程序中生成定期事件。 精度相比Forms.Timer高,100ms間隔時,精度在10ms~20ms之間。(個人電腦測試)

這個類更復雜,它包含了很多成員,使我們可以通過屬性和方法來操作計時器。它還有一個叫做Elapsed的成員事件,每次時間到期就會引發這個事件。這個計時器可以運行在用戶接口線程或工作者線程上。(引用自圖書《C#圖解教程(第四版)》439頁)

示例程序:
1.源代碼

using System;
using System.Diagnostics;
using System.Timers;

namespace Timers
{

class Program
{

static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Timer timer = new Timer();
timer.Enabled = true;//設置是否執行Elapsed事件
timer.Elapsed += new ElapsedEventHandler(printa);//綁定Elapsed事件
timer.Interval =100;//設置時間間隔


while (sw.ElapsedMilliseconds < 1000) //使定時器執行1s,之后停止
{
;
}
timer.Stop();
Console.ReadKey();
}

public static void printa(object sender, ElapsedEventArgs e)
{
Console.WriteLine(DateTime.Now.ToString("hh:mm:ss.fff") + "執行Timer");
}
}

}
2.執行結果

 

結果分析:100ms間隔時,精度在20ms以內。

三、System.Threading.Timer
using System.Threading.Timer;
屬於輕量級計時器,提供以指定的時間間隔執行方法的機制,無法繼承此類。  精度相比Forms.Timer高,100ms間隔時,精度在10ms~20ms之間。(個人電腦測試)

計時器在每次時間到期之后調用回調方法。構造函數結構如下(引用自圖書《C#圖解教程(第四版)》438頁):

 

示例程序:
1.源代碼

 

//構建 Timer
private static Timer timer = new Timer(TimerCallBack, null, 0, 5000);


static void TimerCallBack(object state)
{
Console.WriteLine("{0} 執行一次", DateTime.Now);
//執行完后,重新設置定時器下次執行時間.
//timer.Change(nextTime.Subtract(DateTime.Now), Timeout.InfiniteTimeSpan);
}

 

using System;
using System.Threading;
using System.Diagnostics;

namespace Timers
{
class Program
{
static Stopwatch sw = new Stopwatch();
int TimesCalled = 0;

void Display(object state)
{
Console.WriteLine("{0} {1},{2}", (string)state, ++TimesCalled,/*sw.ElapsedMilliseconds */DateTime.Now.ToString("HH:mm:ss.fff"));
}

static void Main()
{
Program p = new Program();

sw.Start();
Timer myTimer = new Timer(p.Display, "Processing timer event", 2000, 100);
Console.WriteLine("Timer started.");

Console.ReadLine();
}
}

}
2.執行結果

 

結果分析:100ms間隔時,精度在20ms以內。此程序調試時,需要強行停止。

結論:
1、定時器中的執行任務比較耗時時,使用Timers.Timer和Threading.Timer更合適;

2、多線程時,Timers.Timer和Threading.Timer比較,建議使用Timers.Timer。

3、Forms.Timer適用在任務執行時間較短時使用。否則占用窗體UI線程,導致界面卡死等占用資源的情況。

 

相關參考:

1、https://blog.csdn.net/aoxuefeihu/article/details/7483227

2、https://blog.csdn.net/lzp_k2/article/details/84102066

https://blog.csdn.net/lzp_k2/article/details/84102066

 


免責聲明!

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



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