Почему файловый поток не закрыт xmlreader - PullRequest
7 голосов
/ 23 марта 2012

Итак, я использую файловый поток внутри xmlreader

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

Тем не менее, подача файла в xmlreader все еще находится в состоянии блокировки после использования области, странно, я думаю, что xmlreader идетзакрыть поток файлов для меня, не так ли?

Спасибо за помощь.

Ответы [ 4 ]

12 голосов
/ 30 ноября 2012

Вы должны иметь возможность контролировать это через 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
}
8 голосов
/ 23 марта 2012

Вы пробовали это?

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

}

Я не смог найти ничего в документации, в которой явно указано, что XmlReader будет вызывать dispose для базового потока, когда он будет удален. Кроме того, я всегда использую его, как показано выше, и никогда не сталкивался с проблемой.

Просмотр через рефлектор Я также не нахожу случаев, когда он вызывает Dispose() в потоке при создании XmlTextReaderImpl. 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();
    }
}
1 голос
/ 23 марта 2012

Вы должны будете отслеживать FileStream и XmlReader.Для XmlReader потенциально опасно закрывать основной поток.В случае, когда FileStream используется несколькими читателями: если один из этих читателей закроет поток, это приведет к неожиданному отказу других читателей.

Это немного болезненно, поскольку некоторые потоковые читателии авторы закроют основной поток, а другие нет.В качестве лучшей практики я всегда закрываю и избавляюсь от потоков, которые открываю вручную.Это также помогает смягчить некоторые «ошибки» с определенными потоками.
например, Вам необходимо избавиться от GZipStream перед вызовом .ToArray()

0 голосов
/ 13 сентября 2015

Несколько лет спустя, но, может быть, это кому-нибудь поможет ...

Я попробовал метод Эрика, так как он показался мне хорошим решением, но продолжал получать предупреждение CA2202 , когда запускал код VSанализ по нему.

В нижней части 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...
    }
}

Это намного дольше, но, по крайней мере, не выдает никаких предупреждений.

...