Contents

今天又看到一个Coverity报出的问题,说SaveFileDialog在使用完之后没有Dispose。想起了之前写的一篇博文你知道Form.Show()和Form.ShowDialog()的区别吗?。那篇文章总结起来就是说,调用Form.Show()不需要显示的Dispose,但是调用Form.ShowDialog()需要显示的Dispose。那么回到今天的这个问题,SaveFileDialog在使用完之后需要显示的Dispose吗?如果看看MSDN的示例代码,其实它是没有显示Dispose的。那究竟需不需要呢?

还是写段程序来检查一下吧,看看什么时候SaveFileDialog会被Dispose。写一个WinForm,然后加2个按钮,它们对应的响应事件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog s = new SaveFileDialog();
if (DialogResult.OK == s.ShowDialog())
MessageBox.Show("OK");
else
{
MessageBox.Show("Not OK");
}
//s.Dispose();
}

private void button2_Click(object sender, EventArgs e)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}

然后在Visual Studio中加一个函数断点System.ComponentModel.Component.Dispose,因为SaveFileDialog继承自Component,所以当SaveFileDialogDispose时,这个断点应该会被触发。

运行这个程序,点第一个按钮,点完之后发现断点没有被触发。这个时候关掉程序,发现断点被触发了,这个时候要注意看是不是SaveFileDialog,因为好多都是从Component继承下来的,也可以在断点上加一个条件,这样就比较容易观察了。这说明SaveFileDialog在使用完后没有直接被Dispose,一直呆到了程序结束。

再次运行这个程序,点第一个按钮,然后点第二个按钮,这是发现断点被触发了,说明GC会帮我们清理这个没用到的局部变量。

如果把上面代码中的Dispose去掉注释,发现在第一个按钮按完之后就会被Dispose了。

综上,对于SaveFileDialog,我们还是应该在使用完后就显示的Dispose

Contents