title: How to properly stop a multi-threaded .NET windows service?
body: <p>I have a windows service written in C# that creates a truck load of threads and makes many network connections (WMI, SNMP, simple TCP, http). When attempting to stop the windows service using the Services MSC snap-in, the call to stop the service returns relatively quickly but the process continues to run for about 30 seconds or so.</p>
  
  <p>The primary question is what could be the reason that it is taking 30+ seconds to stop. What can I look for and how do I go about looking for it?</p>
  
  <p>The secondary question is why is the service msc snap-in (service controller) returning even though the process is still running. Is there a way to get it to only return when the process is actually killed?</p>
  
  <p>Here is the code in the OnStop method of the service</p>
  
  <pre><code>protected override void OnStop()
  {
     //doing some tracing
     //......
  
     //doing some minor single threaded cleanup here
     //......
  
     base.OnStop();
  
     //doing some tracing here
  }
  </code></pre>
  
  <p><strong>Edit in response to Thread cleanup answers</strong></p>
  
  <p>Many of you have answered that I should keep track of all my threads and then clean them up. I don't think that is a practical approach. Firstly, i don't have access to all managed threads in one location. The software is pretty big with different components, projects and even 3rd party dlls that could all be creating threads. There is no way I can keep track of all of them in one location or have a flag that all threads check (even if i could have all threads check a flag, many threads are blocking on things like semaphores. When they are blocking they can't check. I will have to make them wait with a timeout, then check this global flag and the wait again). </p>
  
  <p>The IsBackround flag is an interesting thing to check. Again though, how can I find out if I have any forground threads running arround? I will have to check every section of the code that creates a thread. Is there any other way, maybe a tool that can help me find this out.</p>
  
  <p>Ultimately though, the process does stop. It would only seem that i need to wait for something. However, if i wait in the OnStop method for X ammount of time, then it takes the process approximately 30 seconds + X to stop. No matter what i try to do, it seems that the process needs approximately 30 seconds (its not always 30 seconds, it can vary) after the OnStop returns for the process to actually stop.</p>