2017-01-16 25 views
0

私は毎日と毎分1回、2つのタイマーを実行するプログラムを持っています。経過時間ごとに、そのタイプに応じてデータベースに新しいレコードを作成します。録音の1日目と2日目にスムーズに録音しますが、3〜4日後に何回か実行すると、重複して録音されます。タイマー経過時間は2回

注:デイリータイマーの場合にのみ発生します。

ID |メッセージ| DateCreated
1001 |毎日| 2017-01-12 03:01:01
2402 |毎日| 2017-01-14 |毎日| 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を参照してください。

簡単な方法の1つは、Saveが呼び出されるたびに新しいタイマーの作成をやめることです。代わりに、作成時にx.Timer.AutoResetfalseに設定します。それをもう止めたり破壊したりしないでください。

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); 
    } 
} 
関連する問題