Jak prawidłowo zatrzymać wielowątkową usługę Windows .NET?

Mam usługę Windows napisaną w języku C #, która tworzy obciążenie wątków ciężarówką i tworzy wiele połączeń sieciowych (WMI, SNMP, prosty TCP, http). Podczas próby zatrzymania usługi systemu Windows przy użyciu przystawki Usługi MSC wywołanie zatrzymania usługi zwraca się stosunkowo szybko, ale proces trwa około 30 sekund.

Podstawowym pytaniem jest, co może być powodem, że zatrzymanie trwa ponad 30 sekund. Czego mogę szukać i jak się do tego zabrać?

Drugie pytanie brzmi: dlaczego usługa msc snap-in (kontroler usług) powraca, mimo że proces nadal działa. Czy istnieje sposób na przywrócenie go tylko wtedy, gdy proces zostanie rzeczywiście zabity?

Oto kod w metodzie OnStop usługi

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

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

   base.OnStop();

   //doing some tracing here
}

Edytuj w odpowiedzi na odpowiedzi Czyszczenie wątków

Wielu z was odpowiedziało, że powinienem śledzić wszystkie moje wątki, a następnie je wyczyścić. Nie sądzę, żeby to było podejście praktyczne. Po pierwsze, nie mam dostępu do wszystkich zarządzanych wątków w jednej lokalizacji. Oprogramowanie jest dość duże z różnymi komponentami, projektami, a nawet bibliotekami zewnętrznymi, które mogą tworzyć wątki. Nie ma możliwości, aby śledzić wszystkie z nich w jednym miejscu lub mieć flagę, która sprawdza wszystkie wątki (nawet jeśli wszystkie wątki mogłyby sprawdzić flagę, wiele wątków blokuje takie rzeczy, jak semafory. Kiedy blokują, mogą Będę musiał sprawić, by poczekały z limitem czasu, a następnie sprawdź tę flagę globalną i jeszcze raz zaczekaj).

Flaga IsBackround to interesująca rzecz do sprawdzenia. Ponownie jednak, jak mogę się dowiedzieć, czy mam jakieś wątki forground uruchomione arround? Będę musiał sprawdzić każdą część kodu, która tworzy wątek. Czy jest jakiś inny sposób, może narzędzie, które pomoże mi to odkryć.

Ostatecznie jednak proces się kończy. Wydawałoby się, że muszę na coś poczekać. Jeśli jednak czekam w metodzie OnStop na ilość czasu X, to zatrzymanie procesu zajmuje około 30 sekund + X. Niezależnie od tego, co próbuję zrobić, wydaje się, że proces wymaga około 30 sekund (nie zawsze 30 sekund, może się różnić) po powrocie OnStop, aby proces rzeczywiście się zatrzymał.

questionAnswers(7)

yourAnswerToTheQuestion