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.
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
throw new ApplicationException("test");
If I put a breakpoint into the main form (the MDI parent) Dispose method
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
I get the following call-stack
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()
with disposing being true.
Afterwards the exception I want to catch is indeed caught as expected in a top level try-catch statement but then the mdi parent form is already closed (why?).
Here some code showing how my top level try-catch works:
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
}
}
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).
What I think I know so far:
- I guess it is not a threading issue (btw. I do also handle the ThreadException event and get nothing there) because I can catch the exception in the UI thread.
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.
Solution in my specific case:
In my case the solution was to not only handle Application.ThreadException
but also use other option like described in this answer. In my case handling Dispatcher.CurrentDispatcher.UnhandledException
did the job. Application.ThreadException
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 Application.ThreadException
did not react on that.