我有一个方法,具体如下:
public int TranslateOOV(string word, Stream logStream)
{
StreamWriter writer = new StreamWriter(logStream);
//Do some logging
//dont close the writer and leave the caller close the stream
}
我没有关闭StreamWriter,因为调用者应该关闭内部流,这会导致内存泄漏吗?
我有一个方法,具体如下:
public int TranslateOOV(string word, Stream logStream)
{
StreamWriter writer = new StreamWriter(logStream);
//Do some logging
//dont close the writer and leave the caller close the stream
}
只是为了好玩,我打开了反编译器,看看在StreamWriter上Dispose方法的作用(想着也许只需要处理底层流资源)。以下是输出的内容:
protected override void Dispose(bool disposing)
{
try
{
if (this.stream != null)
{
if (disposing || (this.Closable || this.stream as __ConsoleStream))
{
this.Flush(true, true);
if (this.mdaHelper != null)
{
GC.SuppressFinalize(this.mdaHelper);
}
}
}
}
finally
{
if (this.Closable)
{
if (this.stream != null)
{
if (disposing)
{
this.stream.Close();
}
this.stream = null;
this.byteBuffer = null;
this.charBuffer = null;
this.encoding = null;
this.encoder = null;
this.charLen = 0;
base.Dispose(disposing);
}
}
}
}
如果流不再被引用,那么它肯定会被垃圾回收器处理掉,因为它实现了IDisposable接口。
让垃圾回收器处理它的问题在于,它被处理的时间是不确定的,取决于几个条件。
因此,理论上它不会导致内存泄漏,但它会使您的应用程序在更长的时间内使用更多的资源,这可能非常低效。
这不是我的强项,但是你应该将StreamWriter放入Using()块中,释放StreamWriter不应该释放流。如果它确实释放了流,你需要返回StreamWriter引用,以便可以进一步清理。
编辑:微软的编码真是太随意了。正如@ckramer的答案所示,StreamWriter不会释放流,而是直接关闭流。深入研究Close方法http://msdn.microsoft.com/en-us/library/system.io.stream.close.aspx
此方法调用Dispose,指定为true以释放所有资源。您不必专门调用Close方法。相反,请确保每个Stream对象都被正确处理。
很高兴看到微软直接忽略了自己的声明。更好的是。
实现者注意事项
在派生类中,不要重写Close方法,而是将所有Stream清理逻辑放在Dispose方法中。
这完全没有意义。他们不仅忽略了他们的第一个陈述,还创建了一个违反开放封闭原则的类,使您能够以可能导致意外场景的方式修改类。对于这样的语句,关闭绝对不应该是虚拟的,或者他们应该纠正考虑此事时的任何推理。