C#中的可调服务计时器

Uto*_*Ltd 3 c# service sleep timer

我正在尝试编写一个无限期运行的Windows服务.用于Linux的Windows窗体和后台程序似乎并不太糟糕,但也许我只是在Windows服务中非常无能为力.与我在这里挖掘的其他一些睡眠或计时器相关的问题不同,醒来或睡觉的时间可以是一个固定的间隔,但并非总是如此.程序从一些数据文件中读取,这些文件可能会指示它改变自己的计划,这必须在下一个唤醒时间生效.它作为一个控制台程序似乎很容易,并在那里表现得很好:

while (true)
{
  // Calculate next time to run.
  DateTime nextRun = NextWakeup();
  TimeSpan nextTime = nextRun - DateTime.Now;
  int sleepMs = (int)nextTime.TotalMilliseconds;
  // Sleep until scheduled time
  System.Threading.Thread.Sleep(sleepMs);
  // Do a code cycle of more stuff here...
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将其作为服务的一部分运行,以便在用户注销时它继续处于活动状态时,服务管理器会顽固地拒绝启动它.我得到了可爱的1053错误,"服务没有及时响应启动或控制请求."

这里有很多相关问题的答案似乎建议不惜一切代价使用计时器而不是线程休眠.如果我做了这样的事情而不是while/sleep组合,我将如何在每次运行时更改定时器间隔?或者这一切都很好,我要设置我的服务错了?

非常感谢提前!

Jam*_*iec 6

Windows服务通常必须在30秒内响应控制请求(通常启动/停止,但也会暂停/恢复).这意味着如果您睡眠服务中的主线程OnStart将返回您引用的错误.

解决问题的方法是在单独的线程上完成工作,您可以按照描述的方式自由地使用线程.只需在服务中启动此线程,OnStart您就可以在30秒的限制内轻松返回.

顺便说一下,while(true)您应该考虑停止服务而不是在30秒限制内返回.如果你有一个线程休眠,服务将无法正常关闭,无需Abort线程(坏)或提供一些正确退出线程的机制.这正是大多数人采用投票方法的原因; 该服务既可以确定其运行时间,也可以确定是否发生了停止请求.只要此轮询频率<30秒,服务将始终正常关闭.