今天做项目的时候遇到一个定时器的问题,具体的需求是需要每天在具体的某个时间出发某个方法,访问程序连接的设备信息,保存到数据库,方便Web端做成报表。
进过多种尝试,最终确定下来思路是(我是把该定时方法放到初始化启动项里面的,每次一打开程序就回去运行这个程序):
1.程序启动的时候启动该方法,获取当前时间和需要运行该方法的那个时间
DateTime dttimeZero = DateTime.Parse(DateTime.Now.ToShortDateString() + " 23:59:59"); //获取当天0点的时间 DateTime dateTime = DateTime.Now; //获取当前时间
2.计算两个之间的时间差,转换成毫秒
TimeSpan ts = new TimeSpan(); //获取时间间隔 ts = dttimeZero - dateTime; //获取时间差 int second = (ts.Hours * 3600 + ts.Minutes * 60 + ts.Seconds) * 1000;
3.然后在新的方法中创建一个线程,但是演示启动这个线程,延时的时间就是上面计算的时间差
Task.Factory.StartNew<int>(() => { Thread.Sleep(second); //休眠的时间==当前时间距离当天0点的时间,转换成毫秒 //具体执行的方法 });
4.首次执行该方法后,下次执行就是24小时后,所以写一while循环,循环间隔为86400000,24小时转换成的毫秒数
while (true) { EQPService eqps = new EQPService(); var eqpInfo = eqps.GetConnectedEquipments();//获取所有连接的设备信息; foreach (var eqpid in eqpInfo) { List<ushort> DATE = new List<ushort>(); DATE.Add(29);//获取设备当前正常Run货累计时长 DATE.Add(39);//获取当前设备运行累计时长 SECSCmd.S1F3Command(eqpid.EQP_ID, DATE, "OEEmonitor"); //询问设备当前累计正常Run货时长 } Thread.Sleep(86400000); }
完整的代码如下:
public void OEEmonitor() { try { DateTime dttimeZero = DateTime.Parse(DateTime.Now.ToShortDateString() + " 23:59:59"); //获取当天0点的时间 DateTime dateTime = DateTime.Now; //获取当前时间 TimeSpan ts = new TimeSpan(); //获取时间间隔 ts = dttimeZero - dateTime; //获取时间差 int second = (ts.Hours * 3600 + ts.Minutes * 60 + ts.Seconds) * 1000; Task.Factory.StartNew<int>(() => { Thread.Sleep(second); //休眠的时间==当前时间距离当天0点的时间,转换成毫秒 while (true) { EQPService eqps = new EQPService(); var eqpInfo = eqps.GetConnectedEquipments();//获取所有连接的设备信息; foreach (var eqpid in eqpInfo) { List<ushort> DATE = new List<ushort>(); DATE.Add(29);//获取设备当前正常Run货累计时长 DATE.Add(39);//获取当前设备运行累计时长 SECSCmd.S1F3Command(eqpid.EQP_ID, DATE, "OEEmonitor"); //询问设备当前累计正常Run货时长 } Thread.Sleep(86400000); } }); } catch (Exception e) { LoggerService.CIMLogger.Error($"Method [{nameof(OEEmonitor)}] is error", e); } }
这是刚写完,本地测试了,还没有正式放到服务器上去运行,最后的总体运行结果有待观察