¿Cómo detener correctamente un servicio de Windows .NET multihebra?

Tengo un servicio de Windows escrito en C # que crea una carga de subprocesos y hace muchas conexiones de red (WMI, SNMP, TCP simple, http). Cuando se intenta detener el servicio de Windows utilizando el complemento MSC de Servicios, la llamada para detener el servicio vuelve relativamente rápido, pero el proceso continúa ejecutándose durante unos 30 segundos aproximadamente.

La pregunta principal es cuál podría ser la razón por la que demoran más de 30 segundos en detenerse. ¿Qué puedo buscar y cómo lo busco?

La pregunta secundaria es por qué el servicio msc snap-in (controlador de servicio) se está devolviendo aunque el proceso aún se está ejecutando. ¿Hay una manera de hacer que solo regrese cuando el proceso realmente se termina?

Aquí está el código en el método OnStop del servicio

protected override void OnStop()
{
   //doing some tracing
   //......

   //doing some minor single threaded cleanup here
   //......

   base.OnStop();

   //doing some tracing here
}

Editar en respuesta a las respuestas de limpieza de subprocesos

Muchos de ustedes han respondido que debería hacer un seguimiento de todos mis hilos y luego limpiarlos. No creo que sea un enfoque práctico. En primer lugar, no tengo acceso a todos los subprocesos administrados en una ubicación. El software es bastante grande con diferentes componentes, proyectos e incluso archivos DLL de terceros que podrían estar creando subprocesos. No hay forma de que pueda hacer un seguimiento de todos ellos en una ubicación o tener una marca que verifique todas las hebras (incluso si pudiera hacer que todas las hebras verifiquen una bandera, muchas hebras están bloqueando cosas como los semáforos. Cuando están bloqueando pueden No tengo que verificar. Tendré que hacer que esperen con un tiempo de espera, a continuación, marque esta bandera global y espere de nuevo).

La bandera de IsBackround es una cosa interesante para comprobar. Sin embargo, una vez más, ¿cómo puedo saber si tengo subprocesos forground alrededor? Tendré que revisar cada sección del código que crea un hilo. ¿Hay alguna otra manera, tal vez una herramienta que pueda ayudarme a descubrir esto?

En última instancia, sin embargo, el proceso se detiene. Solo parecería que tengo que esperar algo. Sin embargo, si espero en el método OnStop durante X una cantidad de tiempo, el proceso tarda aproximadamente 30 segundos + X en detenerse. No importa lo que intente hacer, parece que el proceso necesita aproximadamente 30 segundos (no siempre son 30 segundos, puede variar) después de que OnStop vuelva para que el proceso se detenga.

Respuestas a la pregunta(7)

Su respuesta a la pregunta