views:

140

answers:

1

Hi,

Below is the usual Program.cs content for a windows service program:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService() 
        };
        ServiceBase.Run(ServicesToRun);
    }
}

Is it a bad practice to enclose the ServiceBase.Run(...) in a try-catch block?

Thanks.


EDIT:

Performed some tests and found (test method: send a custom command to the service, which throws an ApplicationException in the OnCustomCommand override):

A. Enclosing ServiceBase.Run() in try/catch does not catch the exception thrown in OnCustomCommand, because the try block was already in scope when the service thread started executing. Therefore, questioning the corectness of this method is irrelevant as long as it doesn't fill its purpose anyway.

B. Adding a handler for AppDomain.CurrentDomain.UnhandledException did not catch the exception either.

However, in both cases the exception showed up in the Windows event log. This pretty much solves my need of knowing when something crashes during service execution but the question remains: are there any cases when a service may silently crash without any trace in the event log?

+2  A: 

That depends on what you are doing. If you intend to treat exceptions and do something useful with them (e.g. retry, run a backup, notify the user and ask for feedback etc) then IMO I do not think this is a bad practice.

As I said, it depends on what you are doing.

dpb
The service's main method is quite filled with try-catches but, even as such, the service seems to shutdown unexpectedly (I say "seems" because I really don't know if it crashes or is manually stopped by somebody; it runs in a different, quite isolated environment). I would like to add the try-catch block around ServiceBase.Run() only to be able to make the difference between stop/crash but I'm not sure if this a valid setup for a long-running process.
Sorin Comanescu
That setup seems fragile indeed. You will have to check for a specific exception to know when the service stopped and when it crashed, but you will also catch other exceptions. If your service is on a remote machine and the network crashes, then you will have a service that didn’t stop and didn’t crash either. Add logging info to OnStop, OnShutdown etc methods for your service and let it log what happens; maybe if you find out what exactly happens to the service you will get a new perspective on things and go from there.
dpb