TMF

Hi all,

This is some kind of philosophy question. What is the correct way to build windows service

And what exactly do I mean
My WS (windows service) have timer and every 1 minute it execute method that need to do something. the method need to run on different thread, and it can be stopped during executing.

So, Whet is the correct way using timer thread timer timespan and wait and how can I stop executing



Re: Visual C# Language The correct way to Windows service

micvos

Start a separate thread in your windows service in which you perform yout task. When it's finished use Thread.Sleep(60000) and then do you task again in an infinite loop. The main thread is still responsive to the message loop so if you get a close there you can terminate the second thread you created.




Re: Visual C# Language The correct way to Windows service

TMF

The problem is that Sleep is sleep. I can't sto pit in the middle. What if my user stoped the servise I'll let him wait for at least 1 minute. and how to handle cases the user stop the servise while it on the run (the inside thread) how to stop it



Re: Visual C# Language The correct way to Windows service

micvos

From the main thread you can terminate the looping thread that's waiting for the next sleep interval. It will be killed instantly.




Re: Visual C# Language The correct way to Windows service

micvos

Here's an example:

namespace WindowsService1
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        Thread thread;

        protected override void OnStart(string[] args)
        {
            thread = new Thread(this.DoWork);
            thread.Start();
        }

        protected override void OnStop()
        {
            thread.Abort();
        }

        public void DoWork()
        {
            while (true)
            {
                DoYourWork();
                Thread.Sleep(60000);
            }
        }
    }

   
}






Re: Visual C# Language The correct way to Windows service

TMF

Inside DoWork() I want to call a new class. Does Thread.Abord() will call the class dispose if not, how can I call it





Re: Visual C# Language The correct way to Windows service

micvos

Inside the DoWork() method you can put your code within a try..catch..finally block. Abort will raise an exception and if this happens during your code you can do the appropriate actions. If you catch the exception don't forget to reraise it.




Re: Visual C# Language The correct way to Windows service

Kea

Aich, aborting threads is bad practice. Instead you should use a monitor which you can pulse from the main thread each time the secondary thread should wake up. To make it quit by itself, have a boolean flag which it checks every time it wakes up.




Re: Visual C# Language The correct way to Windows service

micvos

Kea, that doesn't solve the problem of stopping the service while it's in a sleep state. You have to wait until it comes out of a sleep. Aborting is not really a bad practice if you know what you're doing. Killing a sleeping thread which has no open objects is not dangerous. In the place where you do work with objects you can catch the exception and take your time to clean it all up in a nice way.




Re: Visual C# Language The correct way to Windows service

TMF

So if my service round is, lets say, 2 minutes, the user will have to wait up to 2 minutes after he push the stop service button. This is not a very bad idea but I want to handle this.
I want him to wait up to 20 seconds. I can sleep for 10-20 seconds each time (using Span I can wake my service, check if I need to do somehting, and go back to sleep - if not). But again, What to do inside the thrad action. How can I stop it




Re: Visual C# Language The correct way to Windows service

Kea

Aborting threads should be a last resort to terminate them. I didn't say using monitors and sleep, but using a system timer other than sleep would be a better option, there's no guarantee your thread will sleep for that long. Besides, if the called method should be extended in the future to handle more critical tasks requiring clean up, you have to rewrite that code again to make it work correctly.




Re: Visual C# Language The correct way to Windows service

Vivek Ragunathan

Hi

You can use a timer or wait on an event object in the other thread.
So it might be like WaitForSingleObject(someEvent, 600000);

you might use 2 event objects - one for waking up and doing work and the other for terminating the thread:-

AutoResetEvent doworkEvent;
AutoResetEvent terminateEvent;

public void DoWork()
{
  while (true)
  {
    DoYourWork();
    
    AutoResetEvent[] waitEvents = new AutoResetEvent[] {doworkEvent, terminateEvent };

    int return = WaitHandle.WaitAny(waitEvents, 1 hour, false);

    if (return == WaitHandle.WaitTimeout || return == 0)
    {
      continue;
    }
    else if (return == 1)
    {
      break;
    }
    else
    {
    }
  }
}

Regards
Vivek Ragunathan





Re: Visual C# Language The correct way to Windows service

*Ram*

Hi,

Why don't you go for a System.Timer You could provide the method that you want to be executed at regular intervals as the handler for the 'Elapsed' event of the timer object. You could set the 'Interval' property to 60000. The 'Elapsed' event will be raised for every expiry of the 'Interval' you specified ('AutoReset' property of the Timer object is 'true' by default). When the user stops the service, just invoke 'Stop()' method on the timer object. This should stop raising the 'Elapsed' event & you should be able to stop the service immediately! This, I believe, is a cleaner & less complex implementation.




Re: Visual C# Language The correct way to Windows service

TMF

Let me try explane again my problem:

My service is running just fine. I can stop it (I'm using system.Timer - As RAM say), and while it not on the executing section every thing is just fine.
Where is my problem in the executing secion. inside the executing method I create new class and do some action (include IO, XML parsing etc). It taken about 2-3 minutes from the start till the end of the executing. I need to stop the service inside that section. and when I stop it, no Disposed is called (and I need to do some action while it stop). This is my problem. How to call Dispose method when the user press stop.





Re: Visual C# Language The correct way to Windows service

*Ram*

I believe you can call Dispose from the OnStop method. Override the OnStop method of the service (inherited from Servicebase class) & call Dispose() on the objects.