Объекты C# CA2000:Dispose перед проигрывающим объемом с помощью FileStream/XmlTextReader

У меня есть много кода как это:

FileStream fs = File.Open(@"C:\Temp\SNB-RSS.xml", FileMode.Open); 
using (XmlTextReader reader = new XmlTextReader(fs)) 
{ 
   /* Some other code */
}

Это дает мне соблюдающее предупреждение Анализа кода:

CA2000 : Microsoft.Reliability : In method 'SF_Tester.Run()', object 'fs' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'fs' before all references to it are out of scope.

Если я следую за предложением, и я поместил Файл. Открытый в операторе использования, я получаю это:

CA2202 : Microsoft.Usage : Object 'fs' can be disposed more than once in method 'SF_Tester.Run()'. To avoid generating a System.ObjectDisposedException you should not call Dispose more than one time on an object.: Lines: 39

Я использую VS2010, и я не могу не думать, что я делаю что-то не так, но я не вижу его. Что я делаю неправильно?

8
задан The Diamond Z 27 June 2010 в 18:54
поделиться

4 ответа

Вздох, утомительно, не правда ли? Избегайте всего этого, используя рекомендуемый метод Create ():

 using (var reader = XmlReader.Create(@"C:\Temp\SNB-RSS.xml")) {
     //...
 }
15
ответ дан 5 December 2019 в 06:09
поделиться

Я только догадываюсь; сейчас нет времени на полный анализ.

Предположим, что конструктор XmlTextReader «становится владельцем» переданного потока, и поэтому удаление XmlTextReader также Dispose базового потока. Это объяснило бы поведение, которое вы видите. Возможно, XmlTextReader конструктор может бросить, и в этом случае, оригинальное предупреждение о фс будет иметь смысл. Однако, учитывая эту гипотезу, этот код

        var fs = File.Open(@"C:\Temp\SNB-RSS.xml", FileMode.Open);
        XmlTextReader reader = null;
        try
        {
            reader = new XmlTextReader(fs);
        }
        finally
        {
            if (reader== null)
            {
                fs.Dispose();
            }
        }
        if (reader != null)
        {
            using (reader)
            {
                /* Some other code */
            }
        }

, я думаю, верен, но все же выдает ложное предупреждение. Это выглядит как хороший пример, демонстрирующий ограничения инструментов статического анализа.

Как кто-то сказал, есть еще один API для непосредственного создания читателя из имени файла ( XmlReader.Create () ), который позволяет избежать всего этого (и показывает, насколько хорошо спроектированы API, ориентированные на сценарии. хорошая вещь по удивительному множеству причин).

1
ответ дан 5 December 2019 в 06:09
поделиться

Используйте оператор using также в самом FileStream, как и в XmlTextReader.

http://msdn.microsoft.com/en-us/library/system.io.filestream (VS.71) .aspx .

Grz, Kris.

-1
ответ дан 5 December 2019 в 06:09
поделиться

Это известная проблема

http://connect.microsoft.com/VisualStudio/feedback/details/535118/ca2000-and-ca2202-offer-contradictory-warnings

Если вы используете StreamWriter, скорее чем XmlTextReader (как в приведенном выше решении), вы можете использовать аналогичный метод через соответствующий конструктор; например

var sw = new StreamWriter("filename.txt");

или

var sw = new StreamWriter("filename.txt", /*append to file = */ false );

Из документации не ясно, будет ли первая форма конструктора перезаписана или добавлена ​​к файлу.

1
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: