System.Threading.Timer是.NET框架提供的一個多線程計時器,它可以在指定的時間間隔內自動觸髮指定的回調函數。在本文中,我們將從以下幾個方面來深入探究System.Threading.Timer的使用。
一、Timer 的創建與啟動
我們可以使用 Timer 類的以下構造函數創建一個 Timer 對象:
public Timer(TimerCallback callback, object state, int dueTime, int period);
其中,參數含義如下:
callback
: Timer 回調函數。state
: 傳遞給回調函數的狀態信息。dueTime
: 相對於創建定時器的時間點的初始等待時間(以毫秒為單位)。period
: 觸發回調函數的時間間隔(以毫秒為單位)。
比如下面的代碼創建了一個 Timer,它在程序啟動後 2 秒後開始,每隔 1 秒鐘就會觸發一次回調函數:
class TimerExample
{
static Timer _timer;
static void Main()
{
Console.WriteLine("Timer Example:");
_timer = new Timer(
callback: new TimerCallback(TimerTask),
state: null,
dueTime: 2000, // 2 秒後開始
period: 1000 // 每隔 1 秒鐘觸發回調函數
);
Console.ReadKey();
}
static void TimerTask(object o)
{
// 輸出當前時間
Console.WriteLine(DateTime.Now);
}
}
在執行了上面的代碼後,我們會在控制台上每隔 1 秒鐘看到一次當前時間的輸出。
二、Timer 的停止與釋放
在 Timer 不再使用時,我們應該顯式地停止它並將其資源釋放。我們可以使用 Timer 類的 Change
方法來停止和啟動計時器,示例代碼如下:
_timer.Change(Timeout.Infinite, Timeout.Infinite); // 停止計時器
同時,在適當的時候,我們應該顯式地銷毀 Timer。我們可以在程序退出時,或者 Timer 不再需要時,使用 Timer 的 Dispose
方法來釋放 Timer 佔用的資源。示例代碼如下:
_timer.Dispose();
另外,如果我們不再需要 Timer,則最好將 Timer 對象設置為 null,以便垃圾回收器在適當的時候釋放 Timer 佔用的資源:
_timer = null;
三、Timer 的異常處理
在 Timer 的回調函數中,如果發生了異常,則 Timer 將停止觸發回調函數。因此,在回調函數中要進行異常處理。
我們可以用 try-catch 語句來對發生的異常進行捕獲和處理。實際應用中,我們還需要根據實際情況來選擇適當的處理方式,比如在 catch
子句中記錄日誌、重啟 Timer 等等。
下面的代碼示例演示了如何在回調函數中進行異常處理:
static void TimerTask(object o)
{
try
{
// 向服務器發送請求
SendRequestToServer();
// ... 其他操作 ...
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
四、Timer 的線程安全
Timer 的回調函數可能在任意的線程上執行。因此,在回調函數中,需要注意線程安全問題。
比如,在回調函數中訪問共享數據的時候,需要加鎖:
class TimerExample
{
static readonly object _lockObj = new object();
static int _count = 0;
static Timer _timer;
static void Main()
{
Console.WriteLine("Timer Example:");
_timer = new Timer(
callback: new TimerCallback(TimerTask),
state: null,
dueTime: 2000, // 2 秒後開始
period: 1000 // 每隔 1 秒鐘觸發回調函數
);
Console.ReadKey();
}
static void TimerTask(object o)
{
lock (_lockObj)
{
_count++;
Console.WriteLine($"第 {_count} 次觸發回調函數!");
}
}
}
在上面的代碼中,我們使用了一個靜態的共享計數器 _count,每次回調函數被觸發時,都會將 _count 的值加 1,並輸出當前的計數器值。注意到我們在回調函數中加了鎖來保證 _count 的線程安全。
五、Timer 的參數說明
最後,我們來簡單說明一下 Timer 的一些常用參數:
dueTime
: 相對於創建定時器的時間點的初始等待時間(以毫秒為單位)。period
: 觸發回調函數的時間間隔(以毫秒為單位)。state
: 傳遞給回調函數的狀態信息,可以通過對象包裝實現多個參數傳遞。callback
: Timer 回調函數,可以是任意的TimerCallback
委託。
另外,我們還可以使用 Timer.Change
方法來改變定時器的觸發時間和時間間隔:
dueTime
: 相對於當前時間的初始等待時間(以毫秒為單位),如果dueTime
=Timeout.Infinite
,則定時器不會啟動。period
: 觸發回調函數的時間間隔(以毫秒為單位),如果period
=Timeout.Infinite
,則定時器只觸發一次。如果period
=0,則定時器將根據dueTime
規定的時間觸發。
示例代碼如下:
class TimerExample
{
static Timer _timer;
static void Main()
{
Console.WriteLine("Timer Example:");
_timer = new Timer(
callback: new TimerCallback(TimerTask),
state: null,
dueTime: 5000, // 5 秒後開始觸發回調函數
period: 1000 // 每隔 1 秒鐘觸發回調函數
);
// 5 秒後改變觸發時間和時間間隔
_timer.Change(5000, 2000);
Console.ReadKey();
}
static void TimerTask(object o)
{
// 輸出當前時間
Console.WriteLine(DateTime.Now);
}
}
總結
本文從 Timer 的創建與啟動、停止與釋放、異常處理、線程安全和參數說明等方面進行了詳細說明。希望本文能夠幫助你更好地理解和使用 System.Threading.Timer。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/154975.html