如果.NET对象Pen对象没有显式调用Dispose,它们是如何处理的?

问题描述:

虽然写一个小漆般的应用程序(我自己),我本来下面的代码调用在onclick处理程序:如果.NET对象Pen对象没有显式调用Dispose,它们是如何处理的?

g.DrawEllipse((new Pen(pencolour, penSize)), e.X, e.Y, 1, 1); 

这是我后来改为

Pen pen1 = new Pen(pencolour, penSize); 
g.DrawEllipse(pen1, e.X, e.Y, 1, 1); 
pen1.Dispose(); 

我的问题是:这两段代码是否等价,还是第一个创建了永不丢弃的Pen对象?

当垃圾收集器运行并确定该对象不再被使用时,它们被放置。最好自己处置对象,这样资源就可以立即释放。

也可以考虑使用using声明:

using (Pen pen1 = new Pen(pencolour, penSize)) 
{ 
    g.DrawEllipse(pen1, e.X, e.Y, 1, 1); 
} 

这自动销毁笔,即使DrawEllipse会抛出异常,并且IDE会强制将pen1只能从using块内。

+4

+1 Minor nitpick- GC不调用Dispose,它调用终结器(如果Pen正确实现应该具有相同的效果,假设Dispose从未被用户代码调用)。 – 2012-02-07 19:00:57

+0

很好的解释。还要感谢指向'using'语句的指针。 – 2012-02-07 20:02:57

+0

谢谢你补充说Chris – 2012-02-07 22:24:13

第一个创建永远不会丢弃的笔对象。他们最终会GC'd,但他们会暂时泄漏任何笔管理的非托管资源。

+0

他们没有完全泄漏,他们只是待到晚些时候才处理掉。 – 2012-02-07 19:01:36

+1

因此,“临时”这个词的用法:-)在程序执行的任何时候,我认为它是一个泄漏*未使用的资源没有被清理*和*无法进行手动清理,这就是这种情况。垃圾收集器最终会去清理钢笔的事实是无关紧要的 - 它仍然是*暂时的*泄漏句柄。 – 2012-02-07 19:07:25

配置当然不会被DrawEllipse方法调用,所以这两个片段是不一样的。

由于Pen执行IDisposable,最好使用using statement来确保调用Dispose

using (Pen pen1 = new Pen(pencolour, penSize)) 
{ 
    g.DrawEllipse(pen1, e.X, e.Y, 1, 1); 
} 

如果不这样做,pen1将GC-ED后,因为它超出范围后它不使用。

+0

+1链接到官方文档。 – 2012-02-07 20:31:00