title: How to detect when application terminates?
body: <p>This is a follow up to my <a href="https://stackoverflow.com/questions/1368697/how-to-detect-when-main-thread-terminates">initial question</a> and I would like to present my findings and ask for corrections, ideas and insights. My findings (or rather interpretations) come from people's answers to my previous question, reading MSDN .NET 3.5 documentation and debugging .NET 3.5 code. I hope this will be of value to someone who was wondering like me how to detect when an application terminates. </p>
  
  <p><strong>Events:</strong></p>
  
  <ul>
  <li><p><code>System.AppDomain.CurrentDomain.ProcessExit</code>: raised when process exits, e.g. after the default <code>AppDomain</code> and everything else was unloaded [Total execution time is limited to just 3 seconds!]. For WPF, use <code>System.Windows.Application.Exit</code> instead. For Windows Forms, run code after <code>Application.Run(...)</code> in main method.</p></li>
  <li><p><code>System.AppDomain.CurrentDomain.DomainUnload</code>: raised when an <code>AppDomain</code> other than default <code>AppDomain</code> unloads, e.g. when running classes with unit testing frameworks (MbUnit with TestDriven.NET).</p></li>
  <li><p><code>System.AppDomain.CurrentDomain.UnhandledException</code>: (if handled in default <code>AppDomain</code>:) raised for any unhandled exception in any thread, no matter what <code>AppDomain</code> the thread started in. This means, this can be used as the catch-all for all unhandled exceptions.</p></li>
  <li><p><code>System.Windows.Application.Exit</code>: raised when WPF application (i.e. the default <code>AppDomain</code>) exits gracefully. Override <code>System.Windows.Application.OnExit</code> to take advantage of it.</p></li>
  <li><p>Finalizers (destructors in C#): run when garbage collector frees unmanaged resources. [Total execution time is limited!].</p></li>
  </ul>
  
  <p><strong>Order of events:</strong></p>
  
  <p>WPF application: graceful exit</p>
  
  <ol>
  <li><code>System.Windows.Application.Exit</code></li>
  <li><code>System.AppDomain.CurrentDomain.ProcessExit</code></li>
  <li>Finalizers</li>
  </ol>
  
  <p>WPF application: unhandled exception</p>
  
  <ol>
  <li><code>System.AppDomain.CurrentDomain.UnhandledException</code></li>
  </ol>
  
  <p>MbUnit running inside TestDriven.NET:  passed test (graceful exit)</p>
  
  <ol>
  <li><code>System.AppDomain.CurrentDomain.DomainUnload</code></li>
  <li>Finalizers</li>
  </ol>
  
  <p>MbUnit running inside TestDriven.NET: failed test (unhandled exceptions are handled by MbUnit)</p>
  
  <ol>
  <li><code>AppDomain.CurrentDomain.DomainUnload</code></li>
  <li>Finalizers</li>
  </ol>
  
  <p><strong>Questions:</strong></p>
  
  <ul>
  <li>Are my interpretations/findings correct?</li>
  <li>Do you know of more details that I have
  left out? E.g. what is the total
  execution time for finalizers?</li>
  <li>Do you know of any other events /
  ideas that I be aware of?</li>
  <li>What events are there and what order do they get raised in other applications, e.g. Windows Forms, Web Service, ASP.NET web site, etc?</li>
  </ul>