views:

829

answers:

2

I have a windows service that starts a thread in the OnStart method.

Basically I want to be able to stop the service if something goes really wrong (like an unhandled exception).

Currently I'm using ServiceBase.Stop() but that involves having a ServiceBase instance somewhere visible to the thread, which in turn involves having my instance be declared as public static in the main program.

Is there any "better way" to stop the service? If it isn't ... is it safe to do it that way?

A: 

Check out the example here on how to use the ServiceController class to start and stop services.

Alternatively, you could pass your service instance to the thread when you create it (or set it as an instance variable in the thread class, etc.) without having to make your service class static.

A short example for completeness:

ServiceController sc = new ServiceController("MyService");
sc.Stop();
Eric Petroelje
I don't think it's wise to assume (in all cases) that your service account is going to have access to the service control manager, which is what ServiceController uses. This is what you'd use to control a process from the outside, not a good solution IMO, from the inside.
jlew
Very good point. In that case I would suggest passing the service instance to the thread, or as another poster suggested, making it a singleton.
Eric Petroelje
+1  A: 

The easiest and, in my opinion, cleanest way is to use a public static property of the service class. The only time this won't work is if you are using the same service class to run multiple services in the same process, something that is very rare.

private static MyService m_ServiceInstance;

public static MyService ServiceInstance
{
    get { return m_ServiceInstance; }
}

public MyService()
{
    InitializeComponents();
    //Other initialization
    m_ServiceInstance = this;
}

Injecting the service instance into every method that could possibly need it is an alternative but it can quickly get messy and it has no real advantages over just using a static property.

Stephen Martin