title: WinForms: Why is Dispose called from RunMessageLoopInner?
body: <p>I have experienced the following. In a large application that shows an MDI child form an exception in the child form does also close the parent form.</p>
  
  <p>I am trying to catch the exception and show an error message in a special error form. The desired behavior would be to catch the exception without the parent form being disposed. In the child form I have a button that triggers an exception</p>
  
  <pre><code> throw new ApplicationException("test");
  </code></pre>
  
  <p>If I put a breakpoint into the main form (the MDI parent) Dispose method</p>
  
  <pre><code>protected override void Dispose(bool disposing)
  {
      if (disposing)
      {
          if (components != null)
          {
              components.Dispose();
          }
      }
      base.Dispose(disposing);
  }
  </code></pre>
  
  <p>I get the following call-stack</p>
  
  <pre><code>myApp.dll!myForm.Dispose(bool disposing)
  System.dll!System.ComponentModel.Component.Dispose()
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadWindows.Dispose()
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows()
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.Dispose(bool postQuit)
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reasion, System.Windows.Forms.ApplicationContext context)
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reasion, System.Windows.Forms.ApplicationContext context)
  System.Windows.Forms.dll!System.Windows.Forms.Application.Run()
  </code></pre>
  
  <p>with disposing being <em>true</em>.</p>
  
  <p>Afterwards the <strong>exception I want to catch is indeed caught as expected</strong> in a top level try-catch statement but then the <strong>mdi parent form is already closed (why?)</strong>.</p>
  
  <hr>
  
  <p>Here some code showing how my top level try-catch works:</p>
  
  <pre><code>public class MainApplication
  {
      [STAThread]
      static void Main(string[] args)
      {
          Application.ThreadException += MyThreadExceptionHandler;
          try
          {
              OurMain(args);
          }
          catch(Exception ex)
          {
              MessageBox.Show(ex.Message + "\n" + ex.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
          }
      }
  
      private static void MyThreadExceptionHandler(object sender, ThreadExceptionEventArgs e)
      {
          MessageBox.Show(e.Exception.Message + "\n" + e.Exception.StackTrace, "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
      }
  
      private static void OurMain(string[] args) 
      {
          //run the application
      }
  
  }
  </code></pre>
  
  <hr>
  
  <p>With my question here I am looking for strategies to resolve the issue and learn why the MDI parent form is closing (and finally prevent it from closing).</p>
  
  <p>What I think I know so far:</p>
  
  <ul>
  <li>I guess it is not a threading issue (btw. I do also handle the <a href="https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception(v=vs.110).aspx" rel="nofollow noreferrer">ThreadException</a> event and get nothing there) because I can catch the exception in the UI thread.</li>
  </ul>
  
  <p>Note: I have asked the question in a very general way. Please tell me what specifics information would be relevant for you to be able to answer the question.</p>
  
  <hr>
  
  <p><strong>Solution in my specific case:</strong></p>
  
  <p>In my case the solution was to not only handle <code>Application.ThreadException</code> but also use other option like described in <a href="https://stackoverflow.com/a/1472562/3737186">this answer</a>. In my case handling <code>Dispatcher.CurrentDispatcher.UnhandledException</code> did the job. <code>Application.ThreadException</code> seems only work for pure WinForms but I had encapsulated a Web View and the binding to the Web View triggered the exception and the <code>Application.ThreadException</code> did not react on that.</p>