2

查看来自 GAC 的“System.IO.File.AppendAllText”代码,它调用另一个名为“InternalAppendAllText”的方法,该方法创建一个新的 StreamWriter 并将内容写入文件。

//mscorlib, System.IO
private static void InternalAppendAllText(string path, string contents, Encoding encoding)
{
    using (StreamWriter writer = new StreamWriter(path, true, encoding))
    {
      writer.Write(contents);
    }
}

我的问题是,如果我做了一个 for 循环调用 System.IO.AppentAllText 5 次,例如 StreamWriter 会被创建 5 次,每次迭代都会被初始化和处理,还是只初始化一次?

例子:

for(int i = 1; i < 4; ++i)
{
    System.IO.File.AppendAllText("a", "a");
}
4

2 回答 2

6

using块扩展为等效于以下代码:

StreamWriter writer;
try
{
    writer = new StreamWriter(path, true, encoding))
    writer.Write(contents);
}
finally
{
    if (writer != null)
         writer.Dispose();
}

所以是的,每当一个using块退出时,对象就会被释放。每当您重新输入该函数时,StreamWriter都会初始化一个新函数。

但是请注意,这与垃圾收集器没有任何关系。GC 将在需要时运行,扫描分配的对象,注意到有五个StreamWriter对象没有附加到任何 GC Root,然后丢弃它们。无论您是否调用Dispose或使用都是如此using,这就是 GC 的工作方式。

这里using的作用是释放对象持有的非托管资源——在本例中为文件句柄。如果StreamWriter未销毁或以其他方式明确关闭,则文件将一直锁定以进行编辑,直到您的进程完成或 GC 决定激活。这就是using块和IDisposable交互的用途——确保您明确释放 GC 不知道的对象。

于 2012-11-25T21:00:33.990 回答
3

如果您查看反编译的代码,则 Stream 位于 using 语句中,因此将被清理。它将被初始化所有 5 次,但一旦代码离开 using 语句,它将被清除。

于 2012-11-25T20:56:11.587 回答