Как правильно остановить многопоточную службу Windows .NET?

У меня есть служба Windows, написанная на C #, которая создает загрузку потоков и делает много сетевых подключений (WMI, SNMP, простой TCP, http). При попытке остановить службу Windows с помощью оснастки «Службы MSC» вызов для остановки службы возвращается относительно быстро, но процесс продолжает выполняться в течение примерно 30 секунд.

Основной вопрос заключается в том, что может быть причиной того, что для остановки требуется более 30 секунд. Что я могу искать и как мне искать его?

Дополнительный вопрос - почему сервисная оснастка msc (сервисный контроллер) возвращается, даже если процесс все еще выполняется. Есть ли способ заставить его вернуться только тогда, когда процесс действительно убит?

Вот код в методе OnStop службы

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

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

   base.OnStop();

   //doing some tracing here
}

Редактировать в ответ на ответы очистки темы

Многие из вас ответили, что я должен отслеживать все мои темы, а затем очищать их. Я не думаю, что это практический подход. Во-первых, у меня нет доступа ко всем управляемым потокам в одном месте. Программное обеспечение довольно большое с различными компонентами, проектами и даже сторонними библиотеками, которые могут создавать потоки. Нет никакого способа, которым я могу отслеживать все из них в одном месте или иметь флаг, который проверяют все потоки (даже если бы я мог иметь все потоки, проверяющие флаг, многие потоки блокируют такие вещи, как семафоры. Когда они блокируют, они могут не проверяю. Мне придется заставить их ждать с таймаутом, затем проверить этот глобальный флаг и снова ждать).

Флаг IsBackround - интересная вещь для проверки. Опять же, как я могу узнать, есть ли у меня какие-либо форпредовые потоки, работающие с arround? Мне придется проверять каждый раздел кода, который создает поток. Есть ли другой способ, может быть, инструмент, который может помочь мне выяснить это.

В конечном счете, процесс останавливается. Казалось бы только, что мне нужно чего-то ждать. Однако, если я жду в методе OnStop X времени, то для остановки процесса потребуется примерно 30 секунд + X. Независимо от того, что я пытаюсь сделать, кажется, что процессу требуется приблизительно 30 секунд (его не всегда 30 секунд, он может варьироваться) после возврата OnStop для фактического прекращения процесса.