C# 在Windows服务内的计划中运行方法
我有一个Windows服务,我需要在特定的时间表中运行一个方法。到目前为止,我实现了一个表示计划的类C# 在Windows服务内的计划中运行方法,c#,.net,timer,C#,.net,Timer,我有一个Windows服务,我需要在特定的时间表中运行一个方法。到目前为止,我实现了一个表示计划的类 public class SchaduleTime { public int Hour { get; set; } public int Minute { get; set; } public DateTime Next { get { var now = DateTime.Now;
public class SchaduleTime
{
public int Hour { get; set; }
public int Minute { get; set; }
public DateTime Next
{
get
{
var now = DateTime.Now;
var dt = now.Date;
// the time has passed to execute today?
if (Hour * 60 + Minute < now.Hour * 60 + now.Minute)
{
dt = dt.AddDays(1);
}
return new DateTime(dt.Year, dt.Month, dt.Day, Hour, Minute, 0);
}
}
}
并在计时器字段的已用事件中运行类似的操作:
private void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// do my work.
// programing next:
var nowTicks = DateTime.Now.Ticks;
// get the next schadule.
var next = schadules
.Select(s => new
{
Schadule = s,
IntervalNeeded = s.Next.Ticks - nowTicks
})
.OrderBy(o => o.IntervalNeeded)
.First();
timer.Enabled = false;
timer.Stop();
timer.Interval = (int) new TimeSpan(next.IntervalNeeded).TotalMilliseconds;
timer.Enabled = true;
timer.Start();
}
对我来说,这似乎是一个笨拙的策略或意大利面代码,我的意思是看起来很丑陋
有没有一种方法可以使用一个专门的类来完成这项工作,该类可以与调度或类似.net中的Windows任务调度程序一起工作,或者我的方法很好,我很吃惊?在我看来,你的方法很好。事实上,这是一种启发。我不会想出一个计时器,然后永久地重新安排它
我会做的是——这是严格可选的,就像我说的,你的方法很好——让计时器每分钟启动一次,然后检查是否有事情要做。对于更小的时间分辨率,几秒甚至几毫秒,我不会这么做。但是让你的计时器每分钟运行一次,仅仅检查内存中的数组,然后在95%的情况下直接回到睡眠状态,这并不是一种严重的资源浪费。另外,它将允许更直接和更容易维护的代码。
让我们假设假设的情况,你有14:00的10个时间表。假设您的计时器在13:59:59停止,发生的是:
- 10个时间表声称他们还有1秒钟的时间
- 已用处理程序首先拾取并以1秒的间隔重新启动自身
- 它将在14:00再次停止-此时所有计划都已返回第二天的
Next
ISchedulerFactory factory= new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
scheduler.Start();
// You'll have to implement class performing actual work to be done - ServiceJob
JobDetail jobDetail = new JobDetail("ServiceJob", null, typeof(ServiceJob));
Trigger trigger = TriggerUtils.MakeDailyTrigger();
// Start time could be anytime today
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.Name = "ServiceTrigger";
scheduler.ScheduleJob(jobDetail, trigger);
Quartz负责所有计时器,在请求的时间运行指定的作业,等等。它很简单,有一套很好的解决方案,你不需要实现任何东西
ISchedulerFactory factory= new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
scheduler.Start();
// You'll have to implement class performing actual work to be done - ServiceJob
JobDetail jobDetail = new JobDetail("ServiceJob", null, typeof(ServiceJob));
Trigger trigger = TriggerUtils.MakeDailyTrigger();
// Start time could be anytime today
trigger.StartTimeUtc = DateTime.UtcNow;
trigger.Name = "ServiceTrigger";
scheduler.ScheduleJob(jobDetail, trigger);