0

I have multiple windows services which run 24/7 on a server. For logging events etc. I already use log4net but I want to be able to see if all my services are still running. So I've stumbled upon this question and learned about the ServiceController class. Now I've had the idea to make another service in which I create a ServiceController object per service, and use the WaitForStatus method to be notified when any of the services are stopped. I'd be able to check for any statuses externally through a hosted WCF in the servicecontroller service.

But I've also seen the answer to this question which states a ServiceController should be closed and disposed. Would it be bad to let my ServiceController wait 24/7 until any of my services stopped? Or should I use Quartz or a simple Timer to run a check every x amount of time?

Thanks in advance

Community
  • 1
  • 1
Alexander Derck
  • 11,742
  • 4
  • 43
  • 73
  • 2
    If you manage your resources well in the ServiceController and you create only one instance of it, I dont really see why it would be necessary to close it. However if you do create multiple instances that are not used anymore at some point in the program, you should close them. – Ronald Rozema Dec 24 '15 at 08:46
  • I was just thinking that maybe ServiceController is using other resources which makes it bad to keep one connected to a service at all times? – Alexander Derck Dec 24 '15 at 08:56
  • 1
    Seems very unlikely. It'll keep a handle open to the service (which is fine) and no doubt use some memory for bookkeeping, but nothing significant. The question/answer you link to is talking about leaking instances, not about keeping a single instance around for long periods. – Harry Johnston Dec 24 '15 at 09:26
  • Ok, thanks! It's going to be so good to be able to check and control our services from a distance :) – Alexander Derck Dec 24 '15 at 09:52

1 Answers1

1

You shouldn't. There is no mechanism in Windows to let a service status change generate an event. So ServiceController.WaitForStatus() must poll. It is hard-coded to query the service status 4 times per second, a Thread.Sleep(250) hard-codes the poll interval. Use a decompiler to see this for yourself.

So you basically have many threads in your program, doing nothing but sleep for hours. That's pretty ugly, a thread is an expensive OS object. These threads don't burn any core but the OS thread scheduler is still involved, constantly re-activating the threads when their sleep period expires.

If you need this kind of responsiveness to status changes then it is okayish, but keep in mind that it cannot be more responsive than 250 msec. And keep in mind that increasing the interval by using a Timer sounds attractive but do consider the problem with polling. If you do it, say, once a minute and an admin stops and restarts the service in, say, 30 seconds between two polls then you'll never see the status change. Oops.

Consider to use only one thread that queries many ServiceControllers through their Status property. Your own polling code, minus the cost of the threads.

Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
  • I want to be noticed when one of the services should stop because of an unexpected error. So someone stopping/starting the service isn't a problem, the only time I will restart the service is when some code changed. Would it be better to open the controller, check status and close it again once a minute instead of using the `WaitForStatus` to find out when a service stopped? – Alexander Derck Dec 24 '15 at 12:14
  • "Unexpected error" is pretty fuzzy. A service ought to either log such an error, so you'll have to read the log, and pause itself or it should terminate, so your ServiceController will fail to connect and reading Status produces an exception. Depends. – Hans Passant Dec 24 '15 at 12:22
  • I like the last sentence of your answer, create one servicecontroller per service and poll them every x amount of time – Alexander Derck Dec 24 '15 at 12:43