Friday, April 8, 2011

Windows service stops working, recycling fixes it.

Hi,

I have a windows service that has a timer that fires a method every 30 seconds.

The method then calls thread.sleep() and when it finishes it calls thread.start();

All code in the method is wrapped in a try/catch except for the calls to the tread sleep/start.

For some reason the service stops working, but if I recycle it or set it to recycle upon a crash it works fine.

How can I diagnose the problem?
Is there other events like OnCrash or somethign that I can hook into to dig into the stack trace?

From stackoverflow
  • No, there aren't, but why not just put in a try/catch yourself and log the exception when it occurs?

    Also, I find the call to Sleep and Start very dubious. You shouldn't be using these calls in general for synchronization. Why are you making these calls?

    Blankman : Just to make sure the method I call for every elapsed event doesnt' last longer then the next call to the elapsed event.
    casperOne : @Blankman: So basically you are killing the execution of the method if another event comes in? I think that's a bad idea. I think that you should maybe consider a producer/consumer queue which you would process all the elements of every 30 seconds.
  • I think first and foremost you need to find the reasons why it is crashing. OnCrash? well, if it crashed it won't have much to say, I guess.

  • Hey Blankman,

    If your using .NET to write the service, I suggest you download WinDbg from the Microsoft website.

    Its for serious debugging, which sounds like what you want to do.

    Alternitivly, you can hook into the UnhandledException event

    AppDomain.CurrentDomain.UnhandledException +=  
                     new UnhandledExceptionEventHandler(  
                         OnUnhandledException);  
    
                 //Write some output here
             }
    
    Blankman : i have this already.
  • Its the timer!. Get rid of it and your problem will be solved.

    Check this post for more info .

    You are better off doing the operation like this...

    While (stopSignal = False)
     'do your work'
     Thread.Sleep(yourInterval)
    End While
    

    EDIT: If you want to debug a service and not have to suffer through attaching a debugger, then do this.

    Whether you disagree with this or not, MS has confirmed that its a bug, and removing the timer is the only way to avoid this problem. You should also not be using exceptions as program flow control (Catch and Retry) if you can help it.

    Robert MacLean : -1 disagree. I've used timers very successfully in the past. Provided that the error handling is done correctly, but that would be true for a multitude of situations such as threading and even your suggested way.
    Stephen Martin : This was a bug in .Net 1.0 and 1.1. It has not 'resurfaced' in 2.0. You should be using System.Threading.Timer anyway - it has always been the superior timer.
    casperOne : @StingyJack: This is a HORRIBLE idea for two reasons. First, you are basically spinning a thread, which is wasteful, and second, using Sleep is just a bad, bad idea. The timer is a fine idea.
    StingyJack : @Stephen - Timer is still not fixed in 2.0, 3.0, or 3.5. MS just hasn't updated the KB article. @casper - this is perfectly valid way to poll when its not event driven. I agree that using Thread.Sleep to wait for another thread or for UI updates is bad, but not in this case.
  • A windows service is just the same as a normal application, it's just executed differently. So ask yourself if your normal app didn't crash, but stopped working what could cause it? Lots of things spring to mind like locking issues, concurrency issues etc...

    There is no OnCrash event though but what I do for Windows Services is put all logic in a seperate assembly with a simple start method and that way I can host it in a console application and do testing easily and moving to a windows service is also not too hard.

    Your other option is to attach the Visual Studio debugger to the Windows service and debug as normal.

0 comments:

Post a Comment