Windows 服务计划执行 [英] Windows service scheduled execution
问题描述
如果我有一个需要每 30 秒执行一次任务的 Windows 服务,这更好用;Timer() 类或执行任务然后休眠数秒的循环?
If I have a Windows Service that needs to execute a task every 30 seconds which is better to use; the Timer() class or a loop that executes the task then sleeps for a number of seconds?
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
while (true)
{
try
{
this.ExecuteTask();
System.Threading.Thread.Sleep(30000);
}
catch (Exception)
{
// log the exception
}
}
}
public void ExecutedTask()
{
// do stuff
}
}
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
var timer = new Timer()
{
AutoReset = true,
Interval = 30000,
Enabled = true
};
timer.Elapsed += Timer_Tick;
}
public void Timer_Tick(object sender, ElapsedEventArgs args)
{
try
{
// do stuff
}
catch (Exception)
{
// log the exception
}
}
}
windows 服务将创建 MessageReciever 类的实例并在新线程上执行 CommencePolling 方法.
The windows service will create an instance of the MessageReciever class and execute the CommencePolling method on a new thread.
推荐答案
我认为这真的取决于您的要求.
I think it really depends on your requirement.
案例 1.假设您想从上午 12:00(即 12:00、12:05,...)开始每五分钟运行一次 this.ExecuteTask()
并假设 this 的执行时间.ExecuteTask()
变化(例如,从 30 秒到 2 分钟),也许使用计时器而不是 Thread.Sleep() 似乎是一种更简单的方法(至少对我而言).
case 1.
Suppose you want to run this.ExecuteTask()
every five minutes starting from 12:00AM (i.e., 12:00, 12:05, ...) and suppose the execution time of this.ExecuteTask()
varies (for example, from 30 sec to 2 min), maybe using timer instead of Thread.Sleep() seems to be an easier way of doing it (at least for me).
但是,您也可以使用 Thread.Sleep()
实现此行为,方法是在线程唤醒和 this.ExecuteTask() 完成时获取时间戳,同时计算偏移量)
.
However, you can achieve this behavior with Thread.Sleep()
as well by calculating the offset while taking timestamps on a thread wake-up and on a completion of this.ExecuteTask()
.
案例 2.假设您想在 this.ExecuteTask()
完成后的接下来的 5 分钟内执行任务,使用 Thread.Sleep()
似乎更容易.同样,您也可以使用计时器来实现此行为,方法是每次重置计时器,同时在每次 this.ExecuteTask()
完成时计算偏移量.
case 2.
Suppose you want to perform the task in the next 5 min just after completion of this.ExecuteTask()
, using Thread.Sleep()
seems to be easier. Again, you can achieve this behavior with a timer as well by reseting the timer every time while calculating offsets on every time this.ExecuteTask()
completes.
Note1,对于情况 1,您应该在以下场景中非常小心:如果 this.ExecuteTask()
有时需要超过句点(即它在上面的例子中,从 12:05 开始,到 12:13 结束).
Note1, for the case 1, you should be very careful in the following scenario: what if this.ExecuteTask()
sometimes takes more than the period (i.e. it starts at 12:05 and completes 12:13 in the example above).
这对您的申请意味着什么?将如何处理?
What does this mean to your application and how will it be handled?
一个.完全失败 - 中止服务或在 12:10 中止当前 (12:05) 执行并启动 12:10 执行.
湾没什么大不了的(跳过 12:10 并在 12:15 运行 this.ExecuteTask()
).
a. Total failure - abort the service or abort the current(12:05) execution at 12:10 and launch 12:10 execution.
b. Not a big deal (skip 12:10 one and run this.ExecuteTask()
at 12:15).
c.没什么大不了的,但需要在 12:05 任务完成后立即启动 12:10 执行(如果持续时间超过 5 分钟怎么办??).
c. Not a big deal, but need to launch 12:10 execution immediately after 12:05 task finishes (what if it keeps taking more than 5 min??).
d.即使 12:05 执行当前正在运行,也需要启动 12:10 执行.
d. Need to launch 12:10 execution even though 12:05 execution is currently running.
e.还有什么吗?
对于您在上面选择的策略,您选择的实现(计时器或 Thread.Sleep()
)是否容易支持您的策略?
For the policy you select above, does your choice of implementation (either timer or Thread.Sleep()
) easy to support your policy?
注意 2.您可以在 .NET 中使用多个计时器.请参阅以下文档(尽管它有点老,但它似乎是一个好的开始):比较.NET Framework 类库中的定时器类
Note2. There are several timers you can use in .NET. Please see the following document (even though it's bit aged, but it seems to be a good start): Comparing the Timer Classes in the .NET Framework Class Library
这篇关于Windows 服务计划执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!