幾點說明
- 由於正在做的一個小項目需要使用計時的功能,所以有了這個Timer使用的文章
- 這篇的內容主要參考自MSDN中有關Timer使用的說明
- 以后如果遇到更高層次的使用方法,會繼續更新這篇文章
來自MSDN的說明
System.Timers.Timer
|
Name |
Description |
Method |
Timer 「構造方法」 |
Initializes a new instance of the Timer class, and sets all the properties to their initial values. 初始化一個Timer類的新實例,以及設置初始值,精確度為秒。 |
Method |
Timer(Double) 「構造方法」 |
Initializes a new instance of the Timer class, and sets the Interval property to the specified number of milliseconds. 初始化一個Timer類的新實例,以及設置初始值,精確度為毫秒。 |
Property |
AutoReset 「自動重置」 |
Gets or sets a value indicating whether the Timer should raise the Elapsed event each time the specified interval elapses or only after the first time it elapses. 獲取或設置一個值指示 Timer 是「每次都調用Elapsed 事件」還是「只有第一次調用」。 |
Property |
SynchronizingObject 「同步對象」 |
Gets or sets the object used to marshal event-handler calls that are issued when an interval has elapsed. 獲取或設置用於整理超過設置的時間間隔的事件調用。 |
Method |
Start 「Public」 |
Starts raising the Elapsed event by setting Enabled to true. 通過設置Enalbed為true,馬上開始調用Elapsed |
Method |
Stop 「Public」 |
Stops raising the Elapsed event by setting Enabled to false. 通過設置Enalbed為false,馬上停止調用Elapsed |
Event |
Elapsed 「流逝」 |
Occurs when the interval elapses. 當時間間隔「流逝」時觸發。 |
The Timer component is a server-based timer, which allows you to specify a recurring interval at which the Elapsed event is raised in your application. You can then handle this event to provide regular processing.
Timer組件是一個基於服務器的計時器,它允許你指定一個有間隔的「調用」Elapsed事件的循環。你可以捕獲這個事件來進行你的處理。
Note: When AutoReset is set to false, the Timer raises the Elapsed event only once, after the first Interval has elapsed. To keep raising the Elapsed event on the Interval, set AutoReset to true.
當AutoReset屬性設置為false時,Timer在第一次時間間隔到了之后,只調用一次Elapsed事件。為了保證每次時間間隔都調用Elapsed事件,要設置AutoReset屬性為true
If the SynchronizingObject property is Nothing, the Elapsed event is raised on a ThreadPool thread. If processing of the Elapsed event lasts longer than Interval, the event might be raised again on another ThreadPool thread. In this situation, the event handler should be reentrant.
如果SynchronizingObject 屬性沒有設置, Elapsed事件被一個線程池線程調用。如果Elapsed事件持續的時間比一次間隔要長,這個事件可能會在另一個線程池的線程被調用。在這種情況下,事件處理應該是可重復的。
Note: The event-handling method might run on one thread at the same time that another thread calls the Stop method or sets the Enabled property to false. This might result in the Elapsed event being raised after the timer is stopped.
當一個線程調用Stop方法或設置Enabled屬性為false時,相應的事件處理方法可能會在不同的線程中繼續執行。這可能導致Elapsed事件在計時器已經被停止的時候繼續執行。
Even if SynchronizingObject is not Nothing, Elapsed events can occur after the Dispose or Stop method has been called or after the Enabled property has been set to false, because the signal to raise the Elapsed event is always queued for execution on a thread pool thread. One way to resolve this race condition is to set a flag that tells the event handler for the Elapsed event to ignore subsequent events.
即使SynchronizingObject 已經設置了,Elapsed事件還是會發生在Dispose或Stop方法被調用之后或在Enabled屬性被設置成false后,因為調用Elapsed事件的「符號」總是在一個線程池中列隊執行。一個解決這個競爭條件的方法是設置一個「標識」告訴Elapsed事件處理程序忽略掉隨后的事件。

MSDN示例程序using System;
using System.Timers;
public class Timer1
{
private static System.Timers.Timer aTimer;
public static void Main()
{
// Normally, the timer is declared at the class level,
// so that it stays in scope as long as it is needed.
// If the timer is declared in a long-running method,
// KeepAlive must be used to prevent the JIT compiler
// from allowing aggressive garbage collection to occur
// before the method ends. You can experiment with this
// by commenting out the class-level declaration and
// uncommenting the declaration below; then uncomment
// the GC.KeepAlive(aTimer) at the end of the method.
//System.Timers.Timer aTimer;
// Create a timer with a ten second interval.
aTimer = new System.Timers.Timer(10000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
// Set the Interval to 2 seconds (2000 milliseconds).
aTimer.Interval = 2000;
aTimer.Enabled = true;
Console.WriteLine("Press the Enter key to exit the program.");
Console.ReadLine();
// If the timer is declared in a long-running method, use
// KeepAlive to prevent garbage collection from occurring
// before the method ends.
//GC.KeepAlive(aTimer);
}
// Specify what you want to happen when the Elapsed event is
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}
}
/* This code example produces output similar to the following: Press the Enter key to exit the program. The Elapsed event was raised at 5/20/2007 8:42:27 PM The Elapsed event was raised at 5/20/2007 8:42:29 PM The Elapsed event was raised at 5/20/2007 8:42:31 PM ... */
個人演示程序
TimerWindow


TimerWindow的XAML內容<Window x:Class="csdemo.wpf.controls.Timer.TimerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Timer測試 - http://www.cnblogs.com/sitemanager/" Height="89" Width="287" Loaded="Window_Loaded">
<Grid>
<Button Content="開始" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="btnStart" VerticalAlignment="Top" Width="75" Click="btnStart_Click" />
<Button Content="停止" Height="23" HorizontalAlignment="Left" Margin="93,12,0,0" Name="btnStop" VerticalAlignment="Top" Width="75" Click="btnStop_Click" />
<Button Content="關閉" Height="23" HorizontalAlignment="Left" Margin="174,12,0,0" Name="btnClose" VerticalAlignment="Top" Width="75" Click="btnClose_Click" />
</Grid>
</Window>

TimerWindow的后台代碼using System.Windows;
using System.Timers;
namespace csdemo.wpf.controls.Timer
{
/// <summary>
/// TimerWindow.xaml 的交互邏輯
/// </summary>
public partial class TimerWindow : Window
{
public TimerWindow()
{
InitializeComponent();
}
private void btnStart_Click(object sender, RoutedEventArgs e)
{
aTimer.Start();
}
System.Timers.Timer aTimer = new System.Timers.Timer();
static int elapsedTimes;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000; // 1秒 = 1000毫秒
}
/// <summary>
/// Timer的Elapsed事件處理程序
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
MessageBox.Show((++elapsedTimes).ToString(), "Timer測試 - http://www.cnblogs.com/sitemanager/");
}
private void btnStop_Click(object sender, RoutedEventArgs e)
{
aTimer.Stop();
MessageBox.Show("Timer已停止,之前共觸發次" + (elapsedTimes).ToString() + "事件", "Timer測試 - http://www.cnblogs.com/sitemanager/");
elapsedTimes = 0;
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
aTimer.Dispose(); // 清理aTimer使用的內存
MessageBox.Show("歡迎使用『峻之嶺峰』的WPF控件Demo,您可以在我的博客中看到最新發表的有關編程技術的個人總結。 \n 博客地址: http://www.cnblogs.com/sitemanager/ \n\n如果您是在點擊停止之前點擊此按鈕,將會造成無法停止Timer!\n此時您可以返回您的開發工具停止調試項目。\n或直接在資源管理器中終止進程。\n\n\n 在使用本Demo的同時,由於個人的開發環境不同,所以請不要簡單的拷貝代碼", "『峻之嶺峰』的WPF控件Demo - http://www.cnblogs.com/sitemanager/");
this.Close();
}
}
}
說明:
- 注意之前說過的Timer Elapsed事件的線程有關的問題
- 注意,你可以在任何你想開始計時的地方調用Timer的Start()方法開始計時,調用Stop()方法停止計時。
運行效果
