定时器经过两次

时间:2017-01-16 08:16:45

标签: c# timer

我有一个程序执行两个计时器,一个用于Daily,另一个用于每分钟运行。对于每个经过的时间,它会根据数据类型为数据库创建新记录。它在我继续录制的第1天和第2天提供了平滑的记录,但是在第3天或第4天之后的几次执行之后,它会保留重复输入的记录。

注意:它只适用于每日计时器。

ID |消息| DateCreated
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);
    }
}

更新:已更正 - 每日间隔。

1 个答案:

答案 0 :(得分: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);
    }
}