2

我有一个子表单,其中包含一个RichTextBox加载了 RichText 资源文件的子表单。

当单击关闭子窗体的按钮时(使用Close()),窗体将关闭并返回到父窗体。但是,资源并没有被处置。事实上,在几乎把我的鼠标按钮用完之后,内存真的升级了。

作为测试资源是否最终会被释放,我在父表单上设置了一个表单计时器来加载子表单,在子表单中设置另一个来调用Close(). 这次资源在大约 5 或 6 个打开/关闭周期后被释放。

嗯..我想。所以我改变了设置来模拟现实。这次我将子窗体计时器触发事件​​更改为包含button1.PerformClick(),它触发包含语句button1的按下事件。Close()这次没有释放资源,在我中止测试之前内存使用量上升到 1 GB!

为什么包含的按钮事件与包含Close()的计时器事件不同Close()

好的..这是打开子窗体的父窗体上的代码:-

private void showSplashScreen()
{
    // Instantiating SplashScreen
    SplashScreen splash = new SplashScreen();
    // Displaying SplashScreen
    splash.ShowDialog();
}

这是关闭表单的子表单上的代码:-

private void button1_Click( object sender, EventArgs e )
{
    Close();
}


private void timer1_Tick( object sender, EventArgs e )
{
    button1.PerformClick();
//    Close();
}

当以这种方式运行时,内存使用量会增加。但是如果button1.PerformClick()被注释掉并且Close()未被注释的资源会定期释放

4

2 回答 2

1

根据Form.Close MSDN 文档,如果您使用 ShowDialog,您需要手动处理您的资源。我会在FormClosing事件中这样做。至于为什么当您使用计时器时它会起作用,我不确定。但通常当我使用 aShowDialog并且我正在检查 DialogResult,然后从父级关闭表单。虽然Using像你一样使用它会更干净。

SplashScreen splash = new SplashScreen(); 
DialogResult dr == splash.ShowDialog(); 

if (dr == System.Windows.Forms.DialogResult.OK)
{
    //Do something
}
else
{
    //do something else
}

splash.Close();
splash.Dispose();

表单未在 Close 上处理的两种情况是: (1) 它是多文档界面 (MDI) 应用程序的一部分,并且表单不可见;(2) 您已经使用 ShowDialog 显示了表单。在这些情况下,您将需要手动调用 Dispose 以将表单的所有控件标记为垃圾回收。

于 2012-10-04T15:33:17.353 回答
0

好的伙计们,根据Cyborgx37的想法,我在父窗体上更改了调用方法如下:-

private void showSplashScreen()
{
    // Instantiating SplashScreen.  'using' to allow proper release of resources
    using ( SplashScreen splash = new SplashScreen() ) {
        // Displaying SplashScreen
        splash.ShowDialog();
    }
}

这现在可以正确释放资源。但是,我不明白为什么关闭子表单的计时器允许正确处理资源,而按钮单击关闭则不允许。我什至查看了 IL 代码,这两种方法使用相同的代码。有任何想法吗?

于 2012-10-04T15:10:41.647 回答