views:

236

answers:

4

In my application, I'm seeing that at times the Dispose method on my main form gets called for apparently no reason. I'm not closing the app through the UI, I'm not sending a close windows message or calling Close() anywhere, however the Dispose method still gets called. Here is the call stack:

Bitter.Shell.exe!Bitter.Shell.MainForm.Dispose(bool disposing = true) Line 853 C#
  System.dll!System.ComponentModel.Component.Dispose() + 0x12 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ApplicationContext.Dispose(bool disposing) + 0x35 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.DisposeThreadWindows() + 0x33 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.Dispose(bool postQuit) + 0xf8 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x276 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x61 bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes 
  Bitter.Shell.exe!Bitter.Shell.Program.Main() Line 105 + 0x26 bytes C#

Would the CLR call it if memory was low in attempt to clean up? I know that Windows Mobile does that very thing, but didn't think that happened in the desktop world. Anyone know why this might get called?

EDIT: After a reboot, I no longer see this issue. So it seems like it was somehow due to the state of my system at the time. Either way, the cause should still be identifiable.

+2  A: 

Is an exception being thrown in the UI thread, by any chance?

Jon Skeet
I don't believe so. I have a try catch block in Program.cs that catch anything that doesn't get caught elsewhere and that is usually catches these things.
Mike Hall
But that would catch it *after* the Dispose has been called... if you're breaking into the debugger in Dispose, it would have had a chance to catch it yet.
Jon Skeet
+2  A: 

Add a breakpoint in your dispose method and follow the call stack to see what in your code is calling the dispose method. .NET does not call dispose at any time unless your application is being shutdown by the system or your program itself.

There must be an exception being thrown. Are you nesting message loops?

Qua
The callstack is shown in the question.
Mike Hall
+2  A: 

Are you sure that your form isn't somehow being closed?

EDIT: Click Debug, Exceptions, make VS break on all managed exceptions, and see if there are any exceptions being swallowed.

SLaks
+1  A: 

A try/catch around Application.Run in Program.cs as mentioned in the comment to Jon Skeet's reply won't catch all exceptions.

I would recommend you add a handler for Application.ThreadException before calling Application.Run:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

    try
    {
     ...
     Application.Run(new MainForm());
    }
    catch (Exception ex)
    {
        ... handle exception ...
    }
}

private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
   ... handle exception ...
}
Joe