title: Why code in finally block doesn't execute?
body: <p>It seems that finally block doesn't execute if it other than main thread execute code. Is it possible to force execute finally in that case?</p>
  
  <p>Environment: VS 2010, .Net Framework 4.0.3</p>
  
  <pre><code>class Program
  {
      static void Main(string[] args)
      {
          var h = new AutoResetEvent(false);
  
          ThreadPool.QueueUserWorkItem(
              obj =&gt; TestProc(h));
  
          h.WaitOne();
      }
  
      private static void TestProc(EventWaitHandle h)
      {
          try
          {
              Trace.WriteLine("Try");
              h.Set();
          }
          catch(Exception)
          {
              Trace.WriteLine("Catch");
          }
          finally
          {
              Thread.Sleep(2000);
              Trace.WriteLine("Finally");
          }
      }
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Update:</strong></p>
  
  <p>I found mentions and explanation about that case in MSDN:</p>
  
  <p><strong>ThreadAbortException Class</strong>
  <a href="http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx">http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception.aspx</a></p>
  
  <blockquote>
    <p>When a call is made to the Abort method to destroy a thread, the
    common language runtime throws a ThreadAbortException.
    ThreadAbortException is a special exception that can be caught, but it
    will automatically be raised again at the end of the catch block. When
    this exception is raised, <strong>the runtime executes all the finally blocks
    before ending the thread</strong>. Because the thread can do an unbounded
    computation in the finally blocks or call Thread.ResetAbort to cancel
    the abort, there is <strong>no guarantee that the thread will ever end</strong>. If
    you want to wait until the aborted thread has ended, you can call the
    Thread.Join method. Join is a blocking call that does not return until
    the thread actually stops executing.</p>
  </blockquote>
  
  <p>Note:</p>
  
  <blockquote>
    <p>When the common language runtime (CLR) stops background threads after
    all foreground threads in a managed executable have ended, it does not
    use Thread.Abort. Therefore, you cannot use ThreadAbortException to
    detect when background threads are being terminated by the CLR.</p>
  </blockquote>
  
  <hr>
  
  <p><strong>Foreground and Background Threads</strong> <a href="http://msdn.microsoft.com/en-us/library/h339syd0.aspx">http://msdn.microsoft.com/en-us/library/h339syd0.aspx</a></p>
  
  <blockquote>
    <p>When the runtime stops a background thread because the process is shutting down, no exception is thrown in the thread. However, when threads are stopped because the AppDomain.Unload method unloads the application domain, a ThreadAbortException is thrown in both foreground and background threads. </p>
  </blockquote>
  
  <hr>
  
  <p>So why at the end of application CLR doesn't use AppDomain.Unload method for unloading the application domain before end (kill) of main process?
  Because <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx">http://msdn.microsoft.com/en-us/library/system.appdomain.unload.aspx</a>:</p>
  
  <blockquote>
    <p>When a thread calls Unload, the target domain is marked for unloading.
    The dedicated thread attempts to unload the domain, and all threads in
    the domain are aborted. If a thread does not abort, for example
    because it is executing unmanaged code, or because it is executing a
    finally block, then after a period of time a
    CannotUnloadAppDomainException is thrown in the thread that originally
    called Unload. If the thread that could not be aborted eventually
    ends, the target domain is not unloaded. Thus, <strong>in the .NET Framework
    version 2.0 domain is not guaranteed to unload</strong>, because it might not
    be possible to terminate executing threads.</p>
  </blockquote>
  
  <p>Conclusion: In some cases I need to consider if will my code be executing in background or foreground thread? Is it possible that my code will not finished before application main thread ends all work?</p>