3

如果你正在做例如你只需要一个 using() 用于最外层的流,我是对的吗

MemoryStream mstr = new MemoryStream();

using(StreamWriter w = new StreamWriter(mstr)) {
    ....
}

由于处置 StreamWriter 还应处置/关闭底层流,因此无需这样做吗?:

using(MemoryStream mstr = new MemoryStream())
using(StreamWriter w = new StreamWriter(mstr)) {
    ....
}

(请注意,这些只是示例,关于如何处理包装的流,而不是寻找替代方案,例如使用 StringWriter 等。)

4

5 回答 5

10

using从可读性和可维护性的角度来看,将所有相关资源放在它们自己的块中是一个好主意。例如,在下面的代码中,在最后一个大括号之后,无法尝试访问mstr,因为它的范围限定在它有效的块内:

using (MemoryStream mstr = new MemoryStream())
using (StreamWriter w = new StreamWriter(mstr) {
    ....
}

// cannot attempt to access mstr here

如果你不这样限定它,那么仍然可以mstr在它有效的范围之外访问

MemoryStream mstr = new MemoryStream();
using (StreamWriter w = new StreamWriter(mstr) {
    ....
}

mstr.Write(...); // KABOOM! ObjectDisposedException occurs here!

因此,虽然它可能并不总是必要的(在这种情况下并非如此),但它是一个好主意,因为它既可以阐明并强制执行您对其范围的意图。

于 2009-08-03T18:58:38.067 回答
7

我的经验法则:如果它实现了 IDisposable,请丢弃它。

虽然当前(并且可能永远)调用 StreamWriter.Dispose() 会关闭底层流,但您将来可能使用的其他流派生类可能不会。此外,它似乎也没有真正调用 Dispose(),因此非MemoryStreams 可能无法正确处理(尽管我现在想不出任何会遭受这种情况的影响)。

因此,虽然您可以只安全地处理 StreamWriter,但我发现尽可能始终使用块作为一次性用品是一种更好的做法。

于 2009-08-03T18:56:46.383 回答
4

通过查看 Reflector 中的 StreamWriter.Dispose 方法,看起来底层流已关闭,但未释放。我会将每个流放在一个“使用”块中,以便明确地处理它们。

于 2009-08-03T18:54:22.223 回答
3

回答你的实际问题。TextWriter 的 Dispose 方法

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}

它调用受保护的 Dispose 并将 true 传递给它。来自TextWriter.Dispose 方法(布尔值)

当 disposing 参数为true时,此方法释放此 TextWriter 引用的任何托管对象所持有的所有资源。此方法调用每个引用对象的 Dispose 方法。

然而,最好的做法是将实现 IDisposable 的所有内容包装在 using 块中,因为我们不能保证始终使用true参数调用受保护的 Dipose 方法。

于 2009-08-03T19:05:04.353 回答
0

始终使用using块确实是一种更好的做法。

“总是”,除了一个众所周知的 WCF 代理类案例,其中设计缺陷有时会导致其Dispose方法抛出异常,从而丢失原始异常。

于 2009-08-03T18:56:50.580 回答