【发布时间】:2014-01-17 22:33:15
【问题描述】:
我有显示新表单对话框的示例代码:
private void button1_Click(object sender, EventArgs e)
{
(new Form2()).ShowDialog(this);
GC.Collect();
}
如果表单有按钮、面板标签等,则执行此 form2 的 Dispose 方法,但如果我添加 toolStrip,则不会执行 Dispose 方法。为什么在这些情况下会执行 Dispose?
我读到如果 ShowDialog 显示表单,那么我应该执行 Dispose 方法,但为什么有时没有它它可以工作?
编辑: 可以在 ShowDialog 之后添加 Collect 方法。此方法仅用于测试,会多次执行。
为了检查方法 Dispose 是否被执行,我添加了断点(在调试模式下)。当然在程序结束时执行带有 ToolStrip 的示例。
好的,我知道如何正确实现它,我很感兴趣,如果表单上是 toolStrip,为什么 GC 无法清理?
显示它的最简单的代码是: 示例 1 - 结果 - 100, 示例 2 - 结果 > 0(GC 可以清理), 示例 3 - 始终为 0。 为什么示例 2 和示例 3 如此不同?
private class Form2 : Form
{
public static int disposed = 0;
byte[] data;
private System.Windows.Forms.ToolStrip toolStrip11;
public Form2(bool addToolStrip)
{
data = new byte[100000];
this.Shown += (sender, e) => { this.Close(); };
this.Controls.Add(new Button());
if (addToolStrip)
{
this.toolStrip11 = new System.Windows.Forms.ToolStrip();
this.Controls.Add(this.toolStrip11);
}
}
protected override void Dispose(bool disposing)
{
++disposed;
base.Dispose(disposing);
}
}
private void ShowResult()
{
GC.Collect(); GC.Collect();
GC.WaitForFullGCComplete();
MessageBox.Show(Form2.disposed.ToString());
Form2.disposed = 0;
}
private void button1_Click(object sender, EventArgs e)
{
//proper
for (int i = 0; i < 100; ++i)
{
using(Form2 f = new Form2(true))
{
f.ShowDialog();
}
}
ShowResult();
//ok GC can clean - why yes ?
for (int i = 0; i < 100; ++i)
{
Form2 f = new Form2(false);
f.ShowDialog();
}
ShowResult();
//GC can't clean - why not ?
for (int i = 0; i < 100;a ++i)
{
Form2 f = new Form2(true);
f.ShowDialog();
}
ShowResult();
}
【问题讨论】:
-
我真的不明白你的代码试图做什么。您调用
Collect时没有在该范围内创建任何对象(或删除对所述对象的引用)。如果您想调用Dispose方法,请在using语句中声明您的对话。 -
“为什么在这些情况下会执行 Dispose?” - 您如何确定
Dispose()会在您的Form2上被调用?
标签: c# .net winforms memory-leaks