2

我正在使用 XML 对类对象进行序列化和反序列化时,我遇到了这篇博文,该博文展示了如何在 Windows Phone 7 上使用隔离的存储区域进行序列化和反序列化。Windows Phone 7 是我正在开发的平台:

此示例中,他显式调用Dispose()的唯一对象是 TextReader 对象。我在 MSDN 上查找了 TextReader 对象,发现文档是这样说的:

释放 TextReader 使用的非托管资源,并可选择释放托管资源。

所以我假设他这样做的原因是立即释放 TextReader 对象获取的非托管资源。如果不是因为他的博客文章,我不会想到这样做。显然,我不想开始对可见的每个对象调用 Dispose(),那么对于至少调查特定对象何时应该调用 Dispose() 来说,有什么好的经验法则?是否有一些指导方针或某个地方的列表,至少是需要这种特殊处理的流行 .NET 对象?

4

4 回答 4

5

显然我不想开始在每个对象上调用 Dispose()

错误的。

一般来说,任何实现的对象都IDisposable应该在完成后立即释放,通常使用using语句。

大多数没有非托管资源的对象都没有实现IDisposable(也没有Dispose()方法),因此您无需担心。

唯一的例外是基类,它们IDisposable在某些派生实现有一些东西要处理(例如,、、IEnumeratorComponent)时TextReader实现。
然而,哪些具体的实现需要被处理并不总是很明显(并且它可能随时改变),所以无论如何你都应该处理它们。

于 2013-04-04T03:14:01.770 回答
3

显然,我不想开始对可见的每个对象调用 Dispose(),那么对于至少调查特定对象何时应该调用 Dispose() 来说,有什么好的经验法则?

这不是问题。编译器不允许您在未实现它的对象上调用 Dispose()。

而且您应该为每个实现的对象调用 Dispose() (它将通过IDisposable接口执行)。这是您应该遵循的准则。实际上,这就是对象实现时的含义IDisposable:它具有需要释放的非托管资源。

如果您只需将对象的创建和使用包装在一个using语句中,它就变得不那么繁琐了,例如:

using (DisposableObject obj = new DisposableObject(...))
{
    obj.DoWork();
} // obj.Dispose() is automatically called here, even if an exception is thrown
于 2013-04-04T03:15:31.470 回答
2

实际上,您确实必须处理实现 IDisposable 的对象。

与直接调用 Dispose() 相比,执行此操作的标准方法是:

using(AnyIDisposable obj = ...)
{
    // work with obj here
}
//The Dispose() method is already called here
于 2013-04-04T03:15:29.470 回答
0

如果我错了,请纠正我。据我所知/理解,.NET Framework 的所有类都是托管的(在程序员看来,尽管底层它们可能使用非托管代码),所以理论上你不需要调用 Dispose() 或使用,因为 gc 会小心。但有时非常推荐使用它们,请参阅IDisposable 接口.NET Framework 中哪些托管类分配(或使用)非托管内存?http://blogs.msdn.com/b/kimhamil/archive/2008/11/05/when-to-call-dispose.aspx

编辑:(你是对的菜鸟)为了澄清,我将添加来自IDisposable Interface的 Nayan 答案

建议在以下情况下调用 dispose 或 using:

1.你的类有很多对象,并且有很多交叉引用。即使它全部托管,GC 也可能由于活动引用而无法回收内存。您有机会(而不是编写终结器)解开引用并以您附加它们的方式分解链接。因此,您正在帮助 GC 回收内存。

2.您打开了一些流,这些流一直存在,直到类的对象死亡。即使管理文件/网络等的此类实现,它们也会深入到 Win32 模式下的句柄。因此,您有机会编写一个 Dispose 方法,您可以在其中关闭流。GDI 对象也是如此,甚至更多。

3.您正在编写一个使用非托管资源的类,并且您希望将您的程序集发送给第三方。您最好使用一次性图案,以确保您能够松开手柄以避免泄漏。

4. 你的类实现了许多事件处理程序并将它们与事件挂钩。暴露事件的类的对象,如 Form 等,不会被 GC 释放,因为您的类的本地实现(可能)仍然与这些事件挂钩。您可以在 Dispose 中解开这些事件处理程序;再次帮助GC。

于 2015-05-12T08:58:40.427 回答