我有一个程序执行两个计时器,一个用于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);
}
}
更新:已更正 - 每日间隔。
答案 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);
}
}