C#类对象获取非托管资源的是什么?有清单吗?

时间:2013-04-04 03:11:51

标签: c# .net dispose unmanaged textreader

我正在使用XML进行序列化和反序列化类对象,当我看到这篇博客文章时,它展示了如何使用隔离存储区在Windows Phone 7上执行此操作。 Windows Phone 7是我正在开发的平台:

this example中,他明确调用 Dispose()的唯一对象是TextReader对象。我在MSDN上查找了TextReader对象,发现the documentation说了这个:

  

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

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

4 个答案:

答案 0 :(得分:5)

  

显然我不想开始在

中的每个对象上调用Dispose()

错误。

通常,任何实现IDisposable的对象都应该在您完成后立即处理,通常使用using语句。

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

唯一的例外是在某些派生实现需要处置的情况下实现IDisposable的基类(例如IEnumeratorComponentTextReader)。 /> 但是,并不总是很明显需要处理哪些具体实现(并且可能随时更改),因此无论如何都应该始终处置它们。

答案 1 :(得分: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

答案 2 :(得分:2)

实际上你必须处理实现IDisposable的对象。

与直接调用Dispose()相反的标准方法是:

using(AnyIDisposable obj = ...)
{
    // work with obj here
}
//The Dispose() method is already called here

答案 3 :(得分:0)

如果我错了,请纠正我。 到目前为止,读取/理解.NET Framework的所有内容都是受管理的(对于程序员来说,尽管可能使用非托管代码,但理论上你不需要调用Dispose()或者使用,因为gc会照顾自己。但有时我们建议您使用它们,请参阅IDisposable InterfaceWhich managed classes in .NET Framework allocate (or use) unmanaged memory?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。