Windows服务中的计时器需要重新启动
问题描述:
我创建了一个带有定时器的Windows服务,其中需要设置每个Elapsed定时器事件之后的时间间隔。例如,我希望它每小时都在一小时内开火。Windows服务中的计时器需要重新启动
在Program.cs的:
namespace LabelLoaderService
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
///
static void Main()
{
#if (!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new LabelLoader()
};
ServiceBase.Run(ServicesToRun);
#else
LabelLoader ll = new LabelLoader();
ll.Start();
#endif
}
}
}
在LabelLoader.cs:
namespace LabelLoaderService
{
public partial class LabelLoader : ServiceBase
{
System.Timers.Timer timer = new System.Timers.Timer();
public LabelLoader()
{
InitializeComponent();
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
protected override void OnStart(string[] args)
{
SetTimer();
}
public void Start()
{
// Debug Startup
SetTimer();
}
public void SetTimer()
{
DateTime nextRunTime = GetNextRunTime();
var ts = nextRunTime - DateTime.Now;
timer.Interval = ts.TotalMilliseconds;
timer.AutoReset = true; // tried both true & false
timer.Enabled = true;
GC.KeepAlive(timer); // test - no effect with/without this line
}
void timer_Elapsed(object source, ElapsedEventArgs e)
{
timer.Enabled = false;
// do some work here
SetTimer();
}
如果我installutil这个在我的本地机器,它正确地确定下一个运行时间和执行。但之后它不会运行。如果我重新启动服务,它将运行下一个预定时间,然后再次不再。在我的处理结束时调用SetTimer()是否存在重置Interval并设置timer.Start()的问题?
答
使用System.Threading.Timer
代替 - 在我的经验更适合于服务器一样使用...
编辑 - 按注释一些代码/提示:
下面是一个非常基本的办法避免再入(应在此特定情况下工作正常) - 更好的将是一些lock
/Mutex
或类似
使nextRunTime
实例字段
创建/与启动时间例如
// first the TimerCallback, second the parameter (see AnyParam), then the time to start the first run, then the interval for the rest of the runs
timer = new System.Threading.Timer(new TimerCallback(this.MyTimerHandler), null, 60000, 30000);
创建类似的定时器处理程序
void MyTimerHandler (object AnyParam)
{
if (nextRunTime > DateTime.Now)
return;
nextRunTime = DateTime.MaxValue;
// Do your stuff here
// when finished do
nextRunTime = GetNextRunTime();
}
你应该说timer.Start(); –
事件之间的时间有多长?你有没有尝试过500ms之类的东西?我问,因为在控制台应用程序中使用具有1000毫秒“间隔”的代码对我来说工作得很好。 – dlev
它根据从配置文件中读取的内容而变化。现在我把它设置为每小时一小时。我重新启动它,并按预期在一小时内再次运行。然后我记录了下一次运行时间并将其正确计算到下一个小时。但是当它到达那里时什么都没有发生 – Blaze