什么时候处置?为什么?

Vac*_*ano 10 c# dispose

我问了一个关于这个方法的问题:

// Save an object out to the disk
public static void SerializeObject<T>(this T toSerialize, String filename)
{
    XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
    TextWriter textWriter = new StreamWriter(filename);

    xmlSerializer.Serialize(textWriter, toSerialize);
    textWriter.Close();
}
Run Code Online (Sandbox Code Playgroud)

在回复中,我将此作为补充评论:

确保始终处理一次性资源,例如流和文本阅读器和编写器.在SerializeObject方法中似乎不是这种情况.

所以,我可以说,对于那些编写C#一年或两年的人来说,这似乎是非常蹩脚的,但为什么我必须处理它呢?

是看到testWriter有一个dispose方法,但不应该垃圾收集照顾吗?我从Delphi来到C#.在Delphi中我不得不清理所有东西,所以这不是我想要变懒的情况.我刚刚被告知,如果你强行释放你的对象占用的内存,那么它可能会导致坏事.有人告诉我"让垃圾收集器去做".

  1. 那么,为什么我需要调用dispose?(我的猜测是因为textWriter击中了磁盘.)
  2. 是否有我需要注意的对象列表?(或者知道何时需要调用dispose的简单方法?)

Jon*_*n B 15

这里的经验法则非常简单:始终调用Dispose()实现的对象IDisposable(并非所有对象都可以).您不会总是知道对象必须实现Dispose的原因,但您应该认为它存在是有原因的.

确保您这样做的最简单方法是using:

using (TextWriter tw = new StreamWriter(fileName))
{
   // your code here
}
Run Code Online (Sandbox Code Playgroud)

这将Dispose()在using块的末尾自动调用(它与使用try/catch/finally和finally块中的Dispose()基本相同).

有关Dispose如何与垃圾收集一起使用的更多信息,请参见此处.


Jar*_*Par 12

你是正确的,对于正确编写的代码,GC最终将清理本机资源.该对象将具有终结器,并且在最终确定期间将释放必要的本机资源.

然而,当这种情况发生时非常不确定.此外,它有点倒退,因为您正在使用旨在处理托管内存的GC作为管理本机资源的方法.这导致了有趣的案例,并且可能导致本地资源比预期更长时间保持活跃,导致出现这种情况

  • 文件在不再使用后很长时间打开
  • 资源句柄可能会耗尽,因为GC没有看到足够的内存压力来强制收集并因此运行终结器

using/dispose模式为本机资源的清理添加了确定性并消除了这些问题.