如何在不使用Timer的情况下在Windows服务中进行循环

我希望每隔10秒从Windows服务(使用C#和.NET完成)调用Business层方法。 但是,我不想使用Timer_Elapsed事件,因为如果第一个线程/进程仍在运行,它会启动另一个线程/进程。 我只需要一个单线程方法,因为对同一个Business方法的多次调用会产生不必要的复杂性。

所以我在on_start中添加了一个do-while循环。 我知道这不是正确的方法,因为它产生了这个过程,如果服务被关闭,它就会成为一个孤儿。

我该如何处理这个问题?

问候,Chak

还有另一种获取定时执行的方法,WaitHandle.WaitOne()方法提供了一个超时参数。 这在服务中非常有效,因为它允许您在单个方法调用中实现停止服务定期执行的需要。 模板看起来像这样:

Thread Worker; AutoResetEvent StopRequest = new AutoResetEvent(false); protected override void OnStart(string[] args) { // Start the worker thread Worker = new Thread(DoWork); Worker.Start(); } protected override void OnStop() { // Signal worker to stop and wait until it does StopRequest.Set(); Worker.Join(); } private void DoWork(object arg) { // Worker thread loop for (;;) { // Run this code once every 10 seconds or stop right away if the service // is stopped if (StopRequest.WaitOne(10000)) return; // Do work... //... } } 

使用计时器,但只要输入Timer处理程序方法,就禁用计时器,以便不再引发事件。 在退出处理程序之前,重新启用计时器。

看看这个讨论 ,特别是jsw的回答。 它建议了一种同步机制,以防止多次同时调用业务逻辑。 由于在单独的线程上调用了处理程序,因此无法保证在Elapsed处理程序方法中禁用计时器会阻止并行调用。 使用jsw建议的锁定,并在同步代码块中停止计时器。

或者,您可以使用Timer并将AutoReset属性设置为false 。 这样, Elapsed事件只会被提升一次,您可以手动重置计时器,直到处理程序方法结束。

 while(true) { ..do something Thread.sleep( some time or day); } 
  Thread thread; private void DoWork(object arg) { while (true) { // Run this code once every 20 seconds or stop if the service is stopped try { Thread.Sleep(20000); //Do work.... } catch(ThreadInterruptedException) { return; } } } protected override void OnStart(string[] args) { // Start the thread thread = new Thread(DoWork); mWorker.Start(); } protected override void OnStop() { // interrupt thread and wait until it does thread.Interrupt(); thread.Join(); }