У меня есть много кода как это:
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, и я не могу не думать, что я делаю что-то не так, но я не вижу его. Что я делаю неправильно?
Вздох, утомительно, не правда ли? Избегайте всего этого, используя рекомендуемый метод Create ():
using (var reader = XmlReader.Create(@"C:\Temp\SNB-RSS.xml")) {
//...
}
Я только догадываюсь; сейчас нет времени на полный анализ.
Предположим, что конструктор 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, ориентированные на сценарии. хорошая вещь по удивительному множеству причин).
Используйте оператор using
также в самом FileStream, как и в XmlTextReader.
http://msdn.microsoft.com/en-us/library/system.io.filestream (VS.71) .aspx .
Grz, Kris.
Это известная проблема
Если вы используете StreamWriter, скорее чем XmlTextReader (как в приведенном выше решении), вы можете использовать аналогичный метод через соответствующий конструктор; например
var sw = new StreamWriter("filename.txt");
или
var sw = new StreamWriter("filename.txt", /*append to file = */ false );
Из документации не ясно, будет ли первая форма конструктора перезаписана или добавлена к файлу.