使用.NET Compact Framework时,我是否有理由调用Dispose()方法?

3

最近我接手了一个使用.NET Compact Framework编写的移动设备代码库,我发现代码中到处都是Dispose()调用。

这似乎是在

  • ADO.NET数据库命令
  • Windows窗体

我以为垃圾回收器会处理内存管理。我知道如果没有Dispose(),它们可能会在内存中挂起更长时间,但是有这些调用是否有很大的优势或收益?它似乎会破坏代码的整洁性。

3个回答

5
我知道如果不使用Dispose(),它们在内存中可能会占用更长的时间,但是这些调用是否有很大优势或收益?实际上这取决于Dispose()释放的东西。IDisposable并不一定是关于释放内存,而是关于释放资源。通常情况下,只要没有逻辑上的巨大障碍,您应该在对象上调用Dispose(),而不依赖于垃圾回收来清理资源,除非必要。考虑您正在运行CF,这更加关键。如果您的程序针对资源有限的平台,则尽快清理这些资源非常重要。

这正是我所想的。你认为使用“Using”而不是dispose调用可以改进代码吗? - jaffa
在许多情况下,是的。using语句通常是编写使用可处理类型的代码的更安全、更清洁的方式,前提是您不会在方法之间存储它们。(如果您在同一方法中创建和处理对象,它才真正起作用...) 如果显式调用Dispose(),代码可能还有很大的改进空间,但通过某种机制调用Dispose仍然是一个好主意。 - Reed Copsey
如果我有多个对象需要处理,我不会使用using。嵌套块会很快变得丑陋。例如,如果我要创建4-5个GDI对象,我会在方法的顶部创建它们,并在底部处理它们。但无论如何,他是正确的,尽可能不要依赖GC。首先,GC无法处理释放Dispose所做的资源(非托管资源)。它之所以能够这样做,是因为Dispose 模式指示开发人员应该从Finalizer中调用Dispose,而Finalizer是从GC中调用的。如果开发人员没有这样做,您将泄漏内存。 - Alan
@Alan,即使是多个对象,如果它们都在一个方法中,我仍然更喜欢使用using而不是手动释放。使用using的主要优点是,即使出现异常情况,也可以保证释放资源。您可以堆叠using语句并仅创建一个块,因此它的大小与普通声明相差无几。 - Reed Copsey
@ReedCopsey,你确定可以堆叠Using语句吗?我认为我已经用fixed语句做过了,但是我相信Using语句是非正交的,不允许在没有代码块的情况下使用"using"。 - Alan
@ReedCopsey 好的,我刚刚检查了一下,似乎它确实可以工作...我想知道我当时在想什么,不允许它...但是是的,我确实知道异常处理,如果可以抛出异常,那是一个很好的点。 - Alan

2
通常情况下,但并非总是如此,调用Dispose方法是为了释放非托管资源。作为良好的实践,应该为任何具有Dispose方法的类型调用Dispose。

是的,但 ADO.NET 和 Forms 是托管的,然而 Dispose 调用仍然存在。 - jaffa
2
请记住,在许多托管对象下,存在需要处理的非托管代码调用。同时,调用 dispose 方法是向垃圾回收器发出早期消息,表明该对象可能会被回收。 - Inisheer
2
一个好的 Form 示例是要认识到它内部可能正在执行 Win32 API 调用并保持指向代表窗口等内存位置的指针... 这些东西是非托管的,因此需要释放。 IDisposable 接口提供了一种确保 GC 在清理托管对象时运行正确代码以释放非托管资源的方法。 - Jeff B
没错,我完全同意。如果代码中有我不熟悉的表单,我总是会调用dispose方法,以防万一有自定义绘制方法等。许多GDI对象必须手动释放。简而言之,如果开发人员在你使用的对象中公开了dispose方法,不使用它就是愚蠢的。 - Robbie Dee
调用 Dispose 是为了释放资源。未在所有引用被丢弃之前 Dispose 的托管资源通常会被 最终 释放,但除非所涉及的资源是可替代和充足的,否则这种释放可能不总是及时到足以有用。虽然有时候不需要(或者对于一些设计不良的类来说不能)使用 Dispose,但除非有充分的理由不使用 Dispose,否则应该始终使用 Dispose - supercat

0

.NET 在 IDisposable 对象上调用 Dispose() 方法...即当 GC 清理托管 IDisposable 对象时,它会调用 Dispose() 来清理对象使用的任何非托管资源...在这种情况下,调用 Dispose() 的主要作用似乎是更确定地释放非托管资源(因为 .NET 不使用引用计数器,一个无法访问的对象仍然可能存在并且正在使用内存,反之亦然,一个对象可能已被处理但仍可访问)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接