为什么要调用Dispose?

时间:2009-09-11 15:59:39

标签: c# .net winforms clr

在我的应用程序中,我看到有时我的主窗体上的Dispose方法被调用,显然没有理由。我没有通过UI关闭应用程序,我没有发送关闭的窗口消息或在任何地方调用Close(),但Dispose方法仍然被调用。这是调用堆栈:

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#

如果内存耗尽,CLR是否会调用它来尝试清理?我知道Windows Mobile可以做到这一点,但并不认为这种情况发生在桌面世界。任何人都知道为什么会这样叫?

编辑:重启后,我不再看到这个问题了。所以它似乎是由于当时我的系统状态。无论哪种方式,原因仍应是可识别的。

4 个答案:

答案 0 :(得分:2)

是不是有机会在UI线程中抛出异常?

答案 1 :(得分:2)

在dispose方法中添加断点并按照调用堆栈查看代码中调用dispose方法的内容。 .NET不会在任何时候调用dispose,除非您的应用程序被系统或程序本身关闭。

必须抛出异常。你在嵌套消息循环吗?

答案 2 :(得分:2)

你确定你的表格不是以某种方式被关闭了吗?

编辑:点击调试,例外,对所有托管异常进行VS中断,并查看是否有任何异常被吞下。

答案 3 :(得分:1)

在Jon Skeet的回复评论中提到的Program.cs中的Application.Run的try / catch将不会捕获所有异常。

我建议你在调用Application.Run:

之前为Application.ThreadException添加一个处理程序
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 ...
}