I designed an application that starts an endless Thread
. This Thread
is gathering events from a specific device via a SOAP-API and executes various methods, when specific events are fired.
Now I want all this to run as a service but I'm not sure on how to design the application.
My current plan is to have the service. That service creates an instance of the "poller"-class, that gathers the information. After that, a thread is created that executes the polling-function of "poller" all the time. Should the instance of "poller" and the thread all be created and executed in the OnStart
event of my service-application? And do I have to stop the Thread in the OnStop
event? Or would there be a more clever design?
I'm not sure about this, because I read, that the OnStart
event should not be executed forever. But is it executed forever if I call the Thread
from here?
Thanks for any help, as this is my first service application :-)
The 'poller' class is going to be used from the polling thread that you create, so you have some choices. I would probably go with creating the polling thread in the poller class ctor - there seems to be no reason for the thread to have any greater scope than that. If more devices were added, all you would need to do is create more poller instances.
In OnStart(), create a poller instance, (which itself creates the poller thread), and return, so satisfying the 'OnStart-Event should not be executed forever' condition.
Stopping the thread in OnStop()? First, try the preferred method of stopping threads - don't try to do it at all. Does your service run OK and stop promptly when shut down from the service manager or Task Manager? If so, don't make unnecessary, and possibly counter-productive, work by trying to explicitly stop your polling thread in OnStop() or in the poller class dtor. Just leave OnStop() empty and see if it works OK.
If you find that you have to terminate a thread before the service process is killed by the OS, you may have to resort to devious means to persuade the poller thread to exit promptly, or you may get away with Thread.Interrupt(). Depends..
Just to see, I tried this:
class poller
{
public static void ThreadProc()
{
for (;;)
{
Thread.Sleep(0);
}
}
Thread myThread;
public poller(){
myThread = new Thread(new ThreadStart(ThreadProc));
myThread.Priority = ThreadPriority.BelowNormal;
myThread.Start();
}
};
class WindowsService : ServiceBase
{
poller thisPoller;
public WindowsService()
{
this.ServiceName = "My Windows Service";
this.EventLog.Log = "Application";
this.CanHandlePowerEvent = true;
this.CanHandleSessionChangeEvent = true;
this.CanPauseAndContinue = true;
this.CanShutdown = true;
this.CanStop = true;
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
thisPoller = new poller();
}
protected override void OnStop()
{
base.OnStop();
}
It built and installed OK after fiddling with some project properties and running the right version of installUtil. It started OK, the sleep(0) loop was obviously working because the service appeared on the the 'Processes' tab with CPU use of ~17% on my i7. When I selected 'Stop Service' on the Task Manager Services, the service status went to 'Stopped' straightaway, however it took about 20 seconds for the process to disappear, (?).
For more fun, I really loaded up the box. I stopped the service, uninstalled and rebuilt with:
protected override void OnStart(string[] args)
{
base.OnStart(args);
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
thisPoller = new poller();
}
When I reinstalled and restarted, I knew it was working because I could hear the CPU fan rev up before I could get to the task manager. Sure enough, 100% on all 8 cores.
Stopping was no problem, even with 8 CPU-looping threads. Again, status went to 'Stopped' immediately and the process disappeared abut 20 secs later.
Stting the Sleep interval to '1000000' so that the threads are not running wasn't any problem either - Start OK, Stop OK.