在没有立即关闭的情况下处理新表格的正确方法是什么?
所以在我的应用程序中,我倾向于动态创建新的表单实例,然后使用Form.Show()来显示它们(非模态)。
private void test_click(object sender, EventArgs e) { var form = new myForm(); form.Show(); }
但是,Code Cracker告诉我应该处理这些表格。 所以,我用“使用”语句包装它们,但随后它们在打开后立即关闭。
using (var form = new myForm()) { form.Show(); }
我不想使用Form.ShowDialog(),因为在少数情况下我打开只显示报告的新窗口; 我不需要它们是模态的。
嗯,“代码破解者”似乎是该工具的一个非常合适的术语,它的建议肯定会让你编写破坏你的程序的代码。 Golden Rule 永远不会信任来自静态代码分析工具的IDisposable建议,他们都没有对代码执行有足够的洞察力。 他们永远无法弄清楚哪个Dispose()调用完成了工作。
它看不到的是Form类已经知道如何处置它自己。 它很容易这样做,当窗口关闭时,对象变得无法使用。 当没有窗口时,没有理由继续使用Form对象。 这种奢侈品在.NET中并不常见,但肯定受到45年前为Xerox工作的非常聪明的程序员的启发。
您必须记住一条特殊规则,当您使用ShowDialog()显示窗口时,它不会自行处理。 这是故意的,它使检索对话结果风险太大。 使用show语句进行ShowDialog()调用非常容易,在窗口关闭之前调用不会返回。
表格关闭后是否需要处理表格?
关闭Form
,将向窗口发送WM_CLOSE
消息。 如果你看一下处理WM_CLOSE
消息的WmClose
方法的源代码,你会看到:
-
对于模态表单(使用
ShowDialog
显示),不会调用Dispose
方法,并且关闭后表单存在,您可以使用其属性来获取某些数据,也可以再次显示它。 -
对于非模态表单(使用
Show
),在表单关闭后,将调用Dispose
方法。
所以这是结论:
-
当您使用
Show
方法显示表单时,您不需要(也不能)调用Dispose
。 表格将在关闭后自行处理。 -
使用
ShowDialog
显示表单时,需要手动调用Dispose
。 一个好的做法是在using
块中使用模态forms。
您可以实现某些表单管理器,它将为它显示的每个表单订阅OnFormClosedEvent ,然后它可以处理它们……类似于:
public class FormManager { public T ShowForm() where T : Form, new() { var t = new T(); t.OnFormClosing += DisposeForm; return t; } void DisposeForm(object sender, FormClosedEventArgs args) { ((Form)sender).Dispose(); } }
您甚至可以实施IDisposable并在经理处理时处置所有未处置的表格:)
因此,根据MSDN上的答案,非模态表单会在您关闭它们时自动处理。
我决定通过多次打开我的测试表并关闭它来测试它。 我甚至同时打开了多个实例。 一两秒钟后,这些表格使用的内存被回收,这表明它们正在妥善处理。