有時候我們需要實現延遲執行,或者是定時執行,這個時候可以使用System.Threading.Timer
Timer4個參數
TimerCallback callback:執行的函數,需要傳入一個object類型的參數
object state:callback傳入的參數的值,如果沒有的話寫成null
int dueTime:延遲執行的時間,即幾毫秒后執行操作,單位毫秒
int period:定時執行的時間,即每隔幾毫秒后執行一次操作,單位毫秒
如果要實現延遲執行的效果,那就傳入dueTime,並且把period設置成-1或者Timeout.Infinite
/// <summary>
/// 延遲3秒后執行
/// </summary>
static void Test1() {
Console.WriteLine(DateTime.Now + " 開始...");
Timer timer = new Timer(args => {
try {
Console.WriteLine(DateTime.Now + " 執行操作");
} catch (Exception) {
}
}, null, 3000, Timeout.Infinite);
Console.WriteLine(DateTime.Now + " 等待中...");
}
如果要實現定時執行的效果,就可以傳入period數值,dueTime如果傳入0的話,定時器就會在啟動后立刻執行一次
/// <summary>
/// 立刻執行一次后每隔2秒執行一次
/// </summary>
static void Test2() {
Console.WriteLine(DateTime.Now + " 開始...");
Timer timer = new Timer((p) => {
try {
Console.WriteLine(DateTime.Now + " 執行操作");
} catch (Exception) {
}
}, null, 0, 2000);
Console.WriteLine(DateTime.Now + " 等待中...");
}
定時執行很爽,但是如果業務代碼異常了或者是阻塞了,Test2依然會繼續循環調用,不斷的申請資源,一個處理不好,就很容易導致系統崩潰,那么有咩有什么辦法能讓Timer業務不執行完就不開始下一個任務呢,答案是可以的,就是利用Timer的Change函數來每次延遲執行
/// <summary>
/// 每次延遲2秒執行,執行完畢后再延遲2秒
/// </summary>
static void Test3() {
Console.WriteLine(DateTime.Now + " 開始...");
Timer timer = null;
timer = new Timer((arg) => {
try {
Console.WriteLine(DateTime.Now + " 延遲執行到了");
Thread.Sleep(3000); //模擬3秒的操作耗時
Console.WriteLine(DateTime.Now + " 執行操作");
} catch (Exception) {
} finally {
timer.Change(2000, Timeout.Infinite); //執行完3秒的操作后,再延遲2秒后執行
}
}, null, 2000, Timeout.Infinite); //第一次延遲2秒執行
}
還有就是這個Timer不要像我這樣在方法中當作局部變量使用,因為資源緊張的時候GC有可能會把它給回收了,
Test1和Test3延遲執行不存在這個問題,但是Test2是循環執行就會出現這個問題,如果資源緊張,可能循環走着走着就沒了
所以用的時候一定要避免在方法中作為局部變量用,最好是把創建的Timer對象指向一個非局部變量
