> If the process is still running, it means that your service did not stop
> (yet), issuing the "net stop" command is asynchronous, it always returns
> immediately, whether your service has stopped or not.
I thought it was synchrounous up to a certain time-out, but I don't have a
non-functional service ready to test it ;)
I copied this from a console window on a test system:
| E:\WINNT>net stop a2spoll
| The A2SPoll service is stopping.
| The A2SPoll service was stopped successfully.
|
| E:\WINNT>
A short delay (between 1 and 2 seconds) expired between the "stopping" and
"stopped" messages. The service executable remained active in task manager
for a considerable time after that.
If it hadn't told the SCM it stopped, the services control panel applet
would list the service as "Stopping". It doesn't, and it's even possible
to start the service again while the previous instance is still shown in
task manager (so two instances of the process are running at the same
time).
I think that means the CLR is running finalizers and garbage collection
_after_ the service control function has returned (to the SCM) from
processing the SERVICE_CONTROL_STOP message.
> The fact that you are seeing 100% CPU consumption probably means that the
> finalizer thread is active running the finalizers, you may have some
Not always 100% actually, and the 'fatal execution engine error' doesn't
occur every time either (but >5 times out of 10, and more likely if the
service has been running for a longer time).
> problems cleaning up unmanaged resources if it takes that long (guess your
> COM objects, are you sure they run in the correct apartment?).
As far as I can tell - there's a single STA thread that creates them and
does all processing related to them.
There are a few cases (certain actions started by UI commands) where that
thread will spawn a new working thread that accesses them through Invoke,
but whether that has been done or not seems to make no difference.
> If the it
> takes longer than 30 seconds to terminate the process, the CLR will issue a
> rude thread abort.
Could that be reflected by a 'fatal execution engine error' in the event
log?
> And yes, calling Abort on an other thread than the current thread is
> something you should never do, signal the other threads that they should
> exit, for instance by using a ManualReset Event.
> Is there any particular reason why you would stop a service other than
> shutting down the system?
For installing an update for example, if you want to avoid a reboot.
Willy Denoyette [MVP] - 18 Mar 2006 16:53 GMT
| > If the process is still running, it means that your service did not stop
| > (yet), issuing the "net stop" command is asynchronous, it always returns
| > immediately, whether your service has stopped or not.
I mean your process has stopped, sorry. When the SCM receives the STOPPED
status it considers the service as stopped, even if the process is still
running.
| I thought it was synchrounous up to a certain time-out, but I don't have a
| non-functional service ready to test it ;)
[quoted text clipped - 20 lines]
| _after_ the service control function has returned (to the SCM) from
| processing the SERVICE_CONTROL_STOP message.
| > The fact that you are seeing 100% CPU consumption probably means that the
| > finalizer thread is active running the finalizers, you may have some
[quoted text clipped - 8 lines]
| As far as I can tell - there's a single STA thread that creates them and
| does all processing related to them.
Ok, but initializing a thread to run in an STA is not enough, that thread
needs to pump the message queue. Remember you run in a non UI thread that
means that COM has created an invisible window and an associated window
queue, you need to pump this queue, else the finalizer (running in an MTA)
will not be able to call the underlying RCW's finalizers, resulting in a
blocked finalizer thread. The CLR will release this thread at AD unload time
and will try to run the other pending finalizers, but chances are that there
are so many that there is no time left to run them all before the CLR
terminiates the threads (rude abort).
| There are a few cases (certain actions started by UI commands) where that
| thread will spawn a new working thread that accesses them through Invoke,
| but whether that has been done or not seems to make no difference.
| > If the it
| > takes longer than 30 seconds to terminate the process, the CLR will issue a
| > rude thread abort.
|
| Could that be reflected by a 'fatal execution engine error' in the event
| log?
Possibly, if the thread was running unmanaged code all bad things can
happen.
| > And yes, calling Abort on an other thread than the current thread is
| > something you should never do, signal the other threads that they should
[quoted text clipped - 3 lines]
|
| For installing an update for example, if you want to avoid a reboot.
I see.
Willy.