处理新表格的正确方法
Proper way to dispose a new Form
所以在我的应用程序中,我倾向于动态创建新的表单实例,然后使用 Form.Show()
显示它们(非模态)。
private void test_click(object sender, EventArgs e)
{
var form = new myForm();
form.Show();
}
但是,Code Cracker 告诉我应该处理这些表格。所以,我用 "using" 语句包装它们,但它们在打开后立即关闭。
using (var form = new myForm())
{
form.Show();
}
我不想使用 Form.ShowDialog()
,因为在某些情况下我会打开仅显示报告的新 windows;我不需要它们是模态的。
您可以实施某种形式的表单管理器,它会订阅 OnFormClosedEvent 它显示的每个表单,然后可以处理它们...类似于:
public class FormManager
{
public T ShowForm<T>()
where T : Form, new()
{
var t = new T();
t.OnFormClosing += DisposeForm;
return t;
}
void DisposeForm(object sender, FormClosedEventArgs args)
{
((Form)sender).Dispose();
}
}
您甚至可以执行 IDisposable 并在处置管理器时处置所有未处置的表格 :)
所以根据 MSDN 上的回答,非模态表单会在您关闭它们时自动处理。
我决定通过多次打开我的测试表单然后关闭它们来对此进行测试。我什至同时打开了多个实例。一两秒后,这些表单使用的内存被回收,这表明它们已被妥善处理。
嗯,"code cracker" 似乎是该工具的一个非常合适的术语,它的建议肯定会让您编写破坏程序的代码。黄金法则是从不 相信来自静态代码分析工具的 IDisposable 建议,其中 none 对代码 执行 有足够的洞察力。他们永远无法弄清楚哪个 Dispose() 调用完成了工作。
它看不到的是表单class已经知道如何配置自己了。这样做很容易,当 window 关闭时对象变得不可用。当不再有 window 时,就没有理由继续使用 Form 对象了。这种奢侈品在 .NET 中并不常见,但肯定受到 45 年前为 Xerox 工作的非常聪明的程序员的启发。
只有一条特殊规则需要牢记,当您使用 ShowDialog() 显示 window 时,它 而不是 自行处理。这是故意的,它使检索对话结果的风险太大。对 ShowDialog() 调用使用 using 语句非常容易,调用不会 return 直到 window 关闭。
是否需要在关闭表单后销毁表单?
当您使用 Show()
显示表单时,您不需要释放它,因为它会在关闭后释放。但是当你使用 ShowDialog()
显示表单时,你需要销毁表单,因为它在关闭后不会销毁。
当您关闭一个 Form
,一个处理 WM_CLOSE
消息的 WM_CLOSE
message will be sent to the window. If you take a look at source code of WmClose
方法时,您将看到:
对于模态表单(您使用ShowDialog
显示的),不会调用Dispose
方法并且表单在关闭后存在,您可以使用其属性获取一些数据,或者您可以再次显示它。
对于非模态表单(您使用 Show
显示),在表单关闭后,将调用 Dispose
方法。
所以这是结论:
当您使用 Show
方法显示表单时,您不需要(也不能)调用 Dispose
。表格将在关闭后自行处理。
当您使用 ShowDialog
显示表单时,您需要手动调用 Dispose
。一个好的做法是在 using
块中使用模态形式。
例子
要显示模态对话框,最佳做法是使用 using
块:
//form will be disposed after the using block
using (var f = new MyForm())
{
if (f.ShowDialog() == DialogResult.OK)
{
//Your logic to handle OK here
}
}
对于非模态对话框,显示并忽略它:
var f = new MyForm();
f.Show();
所以在我的应用程序中,我倾向于动态创建新的表单实例,然后使用 Form.Show()
显示它们(非模态)。
private void test_click(object sender, EventArgs e)
{
var form = new myForm();
form.Show();
}
但是,Code Cracker 告诉我应该处理这些表格。所以,我用 "using" 语句包装它们,但它们在打开后立即关闭。
using (var form = new myForm())
{
form.Show();
}
我不想使用 Form.ShowDialog()
,因为在某些情况下我会打开仅显示报告的新 windows;我不需要它们是模态的。
您可以实施某种形式的表单管理器,它会订阅 OnFormClosedEvent 它显示的每个表单,然后可以处理它们...类似于:
public class FormManager
{
public T ShowForm<T>()
where T : Form, new()
{
var t = new T();
t.OnFormClosing += DisposeForm;
return t;
}
void DisposeForm(object sender, FormClosedEventArgs args)
{
((Form)sender).Dispose();
}
}
您甚至可以执行 IDisposable 并在处置管理器时处置所有未处置的表格 :)
所以根据 MSDN 上的回答,非模态表单会在您关闭它们时自动处理。
我决定通过多次打开我的测试表单然后关闭它们来对此进行测试。我什至同时打开了多个实例。一两秒后,这些表单使用的内存被回收,这表明它们已被妥善处理。
嗯,"code cracker" 似乎是该工具的一个非常合适的术语,它的建议肯定会让您编写破坏程序的代码。黄金法则是从不 相信来自静态代码分析工具的 IDisposable 建议,其中 none 对代码 执行 有足够的洞察力。他们永远无法弄清楚哪个 Dispose() 调用完成了工作。
它看不到的是表单class已经知道如何配置自己了。这样做很容易,当 window 关闭时对象变得不可用。当不再有 window 时,就没有理由继续使用 Form 对象了。这种奢侈品在 .NET 中并不常见,但肯定受到 45 年前为 Xerox 工作的非常聪明的程序员的启发。
只有一条特殊规则需要牢记,当您使用 ShowDialog() 显示 window 时,它 而不是 自行处理。这是故意的,它使检索对话结果的风险太大。对 ShowDialog() 调用使用 using 语句非常容易,调用不会 return 直到 window 关闭。
是否需要在关闭表单后销毁表单?
当您使用 Show()
显示表单时,您不需要释放它,因为它会在关闭后释放。但是当你使用 ShowDialog()
显示表单时,你需要销毁表单,因为它在关闭后不会销毁。
当您关闭一个 Form
,一个处理 WM_CLOSE
消息的 WM_CLOSE
message will be sent to the window. If you take a look at source code of WmClose
方法时,您将看到:
对于模态表单(您使用
ShowDialog
显示的),不会调用Dispose
方法并且表单在关闭后存在,您可以使用其属性获取一些数据,或者您可以再次显示它。对于非模态表单(您使用
Show
显示),在表单关闭后,将调用Dispose
方法。
所以这是结论:
当您使用
Show
方法显示表单时,您不需要(也不能)调用Dispose
。表格将在关闭后自行处理。当您使用
ShowDialog
显示表单时,您需要手动调用Dispose
。一个好的做法是在using
块中使用模态形式。
例子
要显示模态对话框,最佳做法是使用 using
块:
//form will be disposed after the using block
using (var f = new MyForm())
{
if (f.ShowDialog() == DialogResult.OK)
{
//Your logic to handle OK here
}
}
对于非模态对话框,显示并忽略它:
var f = new MyForm();
f.Show();