Странное необработанное поведение XmlException - PullRequest
1 голос
/ 10 сентября 2009

Читая этот недавний вопрос о необработанном исключении XmlException, я попытался воспроизвести его как в консольном приложении .NET 2.0, так и в 3.5.

Однако в моем коде он работает точно так, как ожидалось, метод XmlDocument.Load выдает исключение XmlException, поскольку исходный xml-файл содержит символ NULL.

Итак, почему оператор Load в следующем коде (из этого примера) не генерирует исключение XmlException? Более того, почему исключение XmlException не обрабатывается допустимым блоком try, окружающим вызов метода SelectNodes ()?

Хотя я предполагаю, что внутри может происходить какая-то ленивая загрузка / кэширование, разве такое поведение не очень неинтуитивно и не запутанно?

(Предыдущий вопрос ясно показывает скриншот отладчика, жалующегося на то, что SelectNodes () выдал исключение XmlException, но он не обработан ???)

    XmlDocument xDoc = new XmlDocument();
    xDoc.Load(File.FullName);

    //work through each print batch in this queue file
    try
    {
        // This line throws an XmlException but is not handled by the catch!
        XmlNodeList nodeList = xDoc.SelectNodes("Reports/PrintBatch");

        foreach (XmlNode printBatch in nodeList)//xDoc.SelectNodes("Reports/PrintBatch"))
        {
            PrintBatch batch = new PrintBatch();
            batch.LoadBatch(printBatch, File.Extension);
            this.AddBatch(batch);
        }
    }
    catch (XmlException e)
    {
        //this report had an error loading!
        Console.WriteLine(e.Message);
    }

Ответы [ 2 ]

2 голосов
/ 10 сентября 2009

Исключение всегда генерируется XmlDocument.Load, как и ожидалось.

Просто иногда отладчик неправильно понимает номер строки. По моему опыту, следующая строка кода, неправильно выделяемая как исключение исключения, не является редкостью.

Это можно увидеть на снимках экрана: страница с ошибкой ASP правильно показывает, что XmlDocument.Load является метателем, а не оператором SelectNodes.

1 голос
/ 10 сентября 2009

Может быть много причин, по которым вы получаете исключение, а он нет, что, скорее всего, связано с расположением символа NULL. Согласно его стеку, его нулевой символ, кажется, находится в конце XML, в позиции 115227. Возможно, текст перед ним является просто допустимым XML и что дополнительный символ NULL был добавлен в конец файла случайно , Где у вас ваш NULL персонаж?

Или его символ NULL находится внутри атрибута или элемента и считается частью текста. Это также может зависеть от того, является ли XML UTF-8, UTF-16 или другим типом кодировки. Слишком много переменных для рассмотрения.


Когда символ NULL находится в конце, весь файл просто оказывается хорошей строкой с нулевым символом в конце. Тем не менее, как вы говорите, странно, что оно считается необработанным исключением, когда оно находится внутри блока try-Кроме ...

Здесь есть интересное прочтение о перехвате необработанных исключений, но это не объясняет, почему они случаются.

Но если мне нужно угадать ... За классом XML есть куча неуправляемого кода. Из-за символа NULL этот неуправляемый код запутывается и создает ошибку при его освобождении. Вызов SelectNodes () вызовет проверку и обнаружит ошибку, поэтому она возникает. Система начинает обрабатывать обработчик исключений, но сначала пытается освободить xDoc, поскольку он не используется внутри или после блока исключений. Это освобождает неуправляемый код, но неуправляемый код все еще запутан, поэтому он снова вызывает исключение. Это помешает Catch обработать исключение. Вы можете проверить это, добавив второй xDoc.Load () после оператора Catch, что предотвратит освобождение xDoc до Catch.

Тем не менее, это всего лишь предположение ... Мне кажется, ошибка .NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...