1. 程式人生 > >利用定時器做防止誤觸發功能以及多久後執行某個事件

利用定時器做防止誤觸發功能以及多久後執行某個事件

在程式設計中,經常會碰到需要做到如下功能:

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;
        }
    }
}