How to have a loop in a Windows service without using the Timer

前端 未结 5 884
清歌不尽
清歌不尽 2020-11-29 01:29

I want to call a Business layer method from a Windows service (done using C# and .NET) after every 10 seconds. However, i dont want to use the Timer_Elapsed event since it s

相关标签:
5条回答
  • 2020-11-29 02:04

    There's another way to get timed execution, the WaitHandle.WaitOne() method provides a timeout argument. That works very nicely in a service as it lets you implement the need to stop the service and periodic execution in a single method call. The template looks like this:

        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...
                //...
            }
        }
    
    0 讨论(0)
  • 2020-11-29 02:15

    Use a timer, but as soon as you enter the Timer handler method, disable the timer so that no more events are raised. Just before exiting the handler, re-enable the timer.

    0 讨论(0)
  • 2020-11-29 02:18
    while(true)
        {
         ..do something
         Thread.sleep( some time or day);
        }
    
    0 讨论(0)
  • 2020-11-29 02:19

    Check out this discussion, and in particular the answer by jsw. It suggests a synchronization mechanism to prevent multiple simultaneous calls to the business logic. Just disabling the timer in the Elapsed handler method isn't guaranteed to prevent parallel calls since the handler is invoked on a separate thread. Use a lock as jsw suggests, and stop the timer within the synchronized code block.

    Alternatively, you could use a Timer and set the AutoReset property to false. That way, the Elapsed event is raised only once and you can reset the timer manually towards the end of the handler method.

    0 讨论(0)
  • 2020-11-29 02:26
        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();
        }
    
    0 讨论(0)
提交回复
热议问题