为什么文件流没有被xmlreader关闭

所以我在xmlreader使用文件流

 using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) { reader.close() } 

但是,进入xmlreader的文件仍然处于使用范围之后的锁定状态,很奇怪,我认为xmlreader会为我关闭文件流,不是吗?

感谢帮助。

你试过这个吗?

 using(var stream = new FileStream(archivePath, FileMode.Open)) using(var reader = XmlReader.Create(stream, readerSettings)) { } 

我在文档中找不到任何明确声明XmlReader在处理时会在底层流上调用dispose的内容。 另外,我总是如上所示使用它,我从未遇到过问题。

浏览reflection器时我也发现在创建XmlTextReaderImpl时它没有在流上调用Dispose()实例。 XmlTextReaderImpl没有实现Dispose() ,它的Close()方法如下所示:

 internal void Close(bool closeInput) { if (this.parsingFunction != ParsingFunction.ReaderClosed) { while (this.InEntity) { this.PopParsingState(); } this.ps.Close(closeInput); this.curNode = NodeData.None; this.parsingFunction = ParsingFunction.ReaderClosed; this.reportedEncoding = null; this.reportedBaseUri = string.Empty; this.readState = ReadState.Closed; this.fullAttrCleanup = false; this.ResetAttributes(); } } 

您应该能够通过XmlReaderSettings.CloseInput来控制它。

 readerSettings.CloseInput = true; using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), readerSettings)) { // do work with the reader } 

或者,如果您不关心其他读者设置,则更简洁:

 using (XmlReader reader = XmlReader.Create(new FileStream(archivePath, FileMode.Open), new XmlReaderSettings() { CloseInput = true })) { // do work with the reader } 

您需要跟踪FileStreamXmlReaderXmlReader关闭底层流是有潜在危险的。 在多个阅读器使用FileStream的情况下:如果其中一个阅读器要关闭流,这将导致其他阅读器意外失败。

这有点痛苦,因为一些流读者和作者将关闭底层流,而其他人则不然。 作为最佳实践,我总是关闭并处理我手动打开的流。 这也有助于缓解某些流的某些“陷阱”。
例如, 你需要在调用.ToArray()之前.ToArray()

几年后但也许这可能对某人有帮助……

我尝试了Eric的方法,因为它似乎是一个很好的解决方案,但是当我对其运行VS代码分析时,我不断收到警告CA2202 。

在CA2202底部附近,Microsoft建议使用以下内容:

(我稍微修改了它为“XmlReader”。)

 Stream stream = null; try { stream = new FileStream("file.txt", FileMode.Open); using (XmlReader reader = new XmlReader (stream)) { stream = null; // Use the reader object... } } finally { if(stream != null) stream.Dispose(); } 

代替…

 using (Stream stream = new FileStream("file.txt", FileMode.Open)) { using (XmlReader reader = new XmlReader (stream)) { // Use the reader object... } } 

它要长得多,但至少它不会发出任何警告。