使用保护所有可能性
本文关键字:可能性 保护 | 更新日期: 2023-09-27 18:30:58
我找到了以下段落。
using (TextWriter w1 = new StringWriter(...))
using (XmlWriter w2 = new XmlTextWriter(w1))
using (StringReader r1 = new StringReader(...))
using (XmlTextReader r2 = new XmlTextReader(r1))
{
_xslt.Transform(r2, w2);
...
FileOperations.LockFiles();
w1.Close();
w2.Close();
r1.Close();
r2.Close();
}
我的建议是(当然,除了重命名之外)我们可以删除最后四个语句,因为它们是使用 using 声明的,并且当框架感觉合适时,它们将被关闭并正确处理。
然而,其中一位开发人员质疑我,并问了一个非常令人不安的问题。"你完全确定?"然后我得到了鸡爪并推迟了答案。我可能缺少什么吗?
是的,无论如何,using
块将始终释放对象。(好吧,除了停电之类的事件...
此外,对象的处置是非常可预测的,这将始终发生在using
块的末尾。(释放对象后,它们将从终结器队列中删除,并且只是可以进行垃圾回收的常规托管对象,当垃圾回收器发现方便时会发生这种情况。
相反,仅当块内没有未经处理的异常时,才会调用 Close
调用。如果你想让它们被执行,你可以把它们放在finally
块中,这样即使有例外,它们也会被执行。(这就是using
块用来确保它们始终可以释放对象的方法。
很多情况下,using
不会处置有问题的资源。 例如,如果在using
运行时拔下计算机上的插头,则finally
块(using
转换为该块)将不会运行。
using
内复制相同的清理步骤将更适合处理。
如果出现这样的争议,只需启动 ILSpy (http://ilspy.net/) 并查看框架内部,看看它在从 using 语句末尾调用的 Dispose 上实际做了什么。
在这种情况下,您是对的,StringWriter、StringReader、XmlTextReader 和 XmlTextWriter 的所有四个都在 Dispose 方法中执行其处置工作,而 Close 只是调用 Dispose,因此这四行是多余的。(但请注意,StringWriter 和 StringReader 在它们的 Dispose 方法中似乎没有做任何有趣的事情。