利用定時器做防止誤觸發功能以及多久後執行某個事件
在程式設計中,經常會碰到需要做到如下功能:
1.有一個不定時執行的方法A,在執行時需要判斷距離上一次執行過了多長時間,如果超過三秒就繼續執行,如果小於三秒就退出。
2.有一個不定時執行的A方法和B方法,假設:A方法執行完成後,如果3秒內B方法沒有被執行,那麼就執行C方法,如果在3秒內執行了B方法,那麼就執行D方法。(A方法重複執行時分兩種,一種是重複執行會重新整理3秒的等待時間【簡單】,還有一種是不重新整理3秒等待時間【複雜】。
解決方式:
問題1解決:
分析:只需要在每次執行A方法的時候開始計時,下一次執行的時候進行停止計時,判斷時間,然後開啟新的計時
System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); public void A() { stopwatch.Start(); // 開始監視程式碼執行時間 if(stopwatch.IsRunning)//重新整理等待時間 { stopwatch.Stop(); if (stopwatch.Elapsed.TotalSeconds > 3) { //執行需要執行的功能 } else { //小於三秒不執行 } stopwatch.Restart(); } }
問題2解決:
分析:在問題2中,主要判斷的是,在執行B方法時,需要判斷距離A方法執行完後是不是過了3秒,如果是3秒內,就執行D,反之執行C。需要注意的是,B方法不一定會執行,還有可能A方法不一定執行
解決1:重複執行會重新整理3秒等待時間,利用Stopwatch即可實現計算時間
舉例①:1s:A事件執行 3s:A事件執行 (重新整理時間) 5s:B事件執行
判斷:距離最新A事件執行小於三秒,執行D事件
舉例②:1s:A事件執行 5s:B事件執行
判斷:距離A事件執行大於三秒,第4s時執行C事件
解決程式碼:
System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); public void A() { stopwatch.Start(); // 開始監視程式碼執行時間 if(stopwatch.IsRunning)//重新整理等待時間 { stopwatch.Restart(); } } public void B() { stopwatch.Stop(); if (stopwatch.Elapsed.TotalSeconds > 3) { //執行C方法 } else { //執行D方法 } }
解決2:重複執行不會重新整理等待時間,也就是每次執行A事件都要判斷3秒內是否執行了B事件,需要時刻監聽B事件。需要做到:
B事件執行的時候看最近3秒有沒有A事件執行,有的話就執行D
A事件過了三秒後判斷是不是在這三秒內執行了B,沒有的話就執行C
舉例①:1s:A事件執行 3s:A事件執行 5s:B事件執行
判斷:距離第一次的A事件執行大於三秒,距離第二次的A事件執行小於三秒,在第4s時執行一次C事件,在第5s時執行一次D事件
舉例②:1s:A事件執行 3s:A事件執行 7s:B事件執行
判斷:距離第一次和第二次的A事件執行都大於三秒,在第4s時執行第一次C事件,在第6s時執行第二次C事件
解決程式碼:
List<DateTime> listdate = new List<DateTime>();//記錄開始定時的時間
List<System.Timers.Timer> listtime = new List<System.Timers.Timer>();//儲存定時器
List<bool> listif = new List<bool>();//判斷是否執行過B方法
public void A()
{
System.Timers.Timer time = new System.Timers.Timer();
time.Interval = Convert.ToInt32(3000);
time.Elapsed += new System.Timers.ElapsedEventHandler(guoban);
time.AutoReset = false;//設定是執行一次(false)還是一直執行(true);
time.Enabled = true;
listdate.Add(DateTime.Now);
listtime.Add(time);
listif.Add(false);
}
public void B()
{
for (int i = listdate.Count-1; i >0; i--)
{
if((DateTime.Now-listdate[i]).TotalSeconds<=3)
{
//執行D方法
richTextBox1.AppendText("執行D\r\n");
listif[i] = true;
}
if((DateTime.Now - listdate[i]).TotalSeconds > 5)//之前的內容就不需要判斷了
{
break;
}
}
}
public void guoban(object source, System.Timers.ElapsedEventArgs e)
{
for (int i = listdate.Count - 1; i > -1; i--)
{
if ((DateTime.Now - listdate[i]).TotalSeconds <= 4 && (DateTime.Now - listdate[i]).TotalSeconds >= 3)//判斷最近的幾次是不是執行過了,但是要確保是已經過了三秒的了
{
if(!listif[i])
{
//執行C方法
richTextBox1.AppendText("執行C\r\n");
listif[i] = true;
}
}
if ((DateTime.Now - listdate[i]).TotalSeconds > 5)//之前的內容就不需要判斷了
{
break;
}
}
}