2017-01-16 77 views
0

我有一個程序執行兩個計時器,一個用於每日,另一個每分鐘運行一次。對於每一段時間,它都會根據數據庫的類型爲數據庫創建一條新記錄。它可以在連續錄製的第一天和第二天提供流暢的錄製,但在第三天或第四天之後可能會執行多次錄製,從而可以保存重複錄製的錄製內容。計時器經過兩次

注意:它只發生在每日定時器。

ID |留言|日期創建
1001 |每日| 2017-01-12 03:01:01
2402 |每日| 2017-01-13 03:01:02
2503 |每日| 2017-01-14 03:01:03
3702 |每日| 2017-01-14 03:01:04
3502 |每日| 2017-01-15 03:01:04
4520 |每日| 2017-01-15 01:01:05
5540 |每日| 2017-01-15 03:01:05
7520 |每日| 2017-01-15 03:01:05

可能的原因是什麼?是否有可能沿途創建了一些計時器實例?

class Program { 
    static void Main(string[] args) { 
     List<TimerClass> timerList = new List<TimerClass>(); 
     timerList.Add(new TimerClass() {ID = 1, Type = "Minute"}); 
     timerList.Add(new TimerClass() {ID = 2, Type = "Daily"}); 
     Execute(); 
    } 

    //Method to execute all default timers 
    static void Execute(){ 
     foreach(TimerClass x in timerList){ 
      x.Timer = new System.Timers.Timer(); 
      x._exec = new ExecTimer(Save); 
      switch(x.Type){ 
       case "Minute": 
        x.Timer.Interval = 60000; 
        break; 
       case "Daily"; 
        x.Timer.Interval = 86400000; 
        break; 
      } 
      x.Timer.Start(); 
     } 
    } 

    //method for creating record 
    public void Save(int id){ 
     TimerClass i = timerList.Where(x => x.ID === id); 
     double interval = i.Timer.Interval; 
     i.Timer.Stop(); 
     i.Timer.Dispose(); 

     DB.Insert(x.Type, DateTime.Now.ToString()); 
     Console.WriteLine("Successfuly Saved"); 

     //recreate Timer 
     i.Timer = new System.Timers.Timer(); 
     i._exec = new ExecTimer(Save); 
     i.Timer.Interval = interval; 
     i.Timer.Start(); 
    } 
} 


//delegate for timer execution 
public delegate void ExecTimer(int id); 
//Timer Class 
public class TimerClass{ 
    public System.Timers.Timer Timer { get; set; } 
    public int ID { get; set; } 
    public string Type {get; set;} 

    public ExecTimer _exec; 
    public void _timer_Elapsed(object sender, ElapsedEventArgs e){ 
     _exec(ID); 
    } 
} 

UPDATE:更正 - 每日間隔。

+1

你確定每天計時器的「間隔」嗎?我認爲它應該是1000 * 60 * 60 * 24 = 86400000. – wkl

+2

另外,在定時器上使用'AutoReset = true;'時,不應該有必要在處理時創建一個新的。 – wkl

+0

謝謝@wkl,我只是每小時做一次平均時間,只是爲了測試每日。 – maragon1

回答

2

當您調用Save時,您破壞的「舊」計時器可能已經安排了其下一次執行。
當你每次創建一個新的計時器時,你會最終看到舊的計算器仍然在後臺運行+新的計時器。
有關更多信息,請參閱https://stackoverflow.com/a/18280560/3439544

一個簡單的方法就是在每次調用Save時停止創建一個新的定時器。請在創建時將x.Timer.AutoReset設置爲false。不要停止/銷燬它,並在數據庫調用後繼續啓動它。

class Program { 
    static void Main(string[] args) { 
     List<TimerClass> timerList = new List<TimerClass>(); 
     timerList.Add(new TimerClass() {ID = 1, Type = "Minute"}); 
     timerList.Add(new TimerClass() {ID = 2, Type = "Daily"}); 
     Execute(); 
    } 

    //Method to execute all default timers 
    static void Execute(){ 
     foreach(TimerClass x in timerList){ 
      x.Timer = new System.Timers.Timer(); 
      x.Timer.AutoReset = false; 
      x._exec = new ExecTimer(Save); 
      switch(x.Type){ 
       case "Minute": 
        x.Timer.Interval = 60000; 
       case "Daily"; 
        x.Timer.Interval = 360000; 
      } 
      x.Timer.Start(); 
     } 
    } 

    //method for creating record 
    public void Save(int id){ 
     TimerClass i = timerList.Where(x => x.ID === id); 

     DB.Insert(x.Type, DateTime.Now.ToString()); 
     Console.WriteLine("Successfuly Saved"); 

     // Re-start the timer 
     i.Timer.Start(); 
    } 
} 


//delegate for timer execution 
public delegate void ExecTimer(int id); 
//Timer Class 
public class TimerClass{ 
    public System.Timers.Timer Timer { get; set; } 
    public int ID { get; set; } 
    public string Type {get; set;} 

    public ExecTimer _exec; 
    public void _timer_Elapsed(object sender, ElapsedEventArgs e){ 
     _exec(ID); 
    } 
}