在阅读有关未处理的XmlException的this recent question时,我尝试在.NET 2.0和3.5控制台应用程序中重现它。
但是,在我的代码中,它的行为完全符合预期,因为源XmlDocument.Load文件包含空字符,所以它会抛出一个XmlException。
那么,为什么下面的代码(来自该示例)中的Load语句不抛出XmlException呢?更重要的是,为什么SelectNodes()方法调用周围的有效XmlException块不处理try?
虽然我猜测内部可能正在进行某种延迟加载/缓存,但这种行为不是非常不直观和令人困惑吗?
(前面的问题清楚地显示了调试器的屏幕截图,该屏幕截图抱怨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);
    }发布于 2009-09-10 13:22:39
异常总是如预期的那样由XmlDocument.Load抛出。
只是有时候调试器会把行号弄错。根据我的经验,下一行代码被错误地突出显示为异常的抛出者并不少见。
你可以在屏幕截图中看到这一点: ASP error页面正确地显示了XmlDocument.Load是抛出者,而不是SelectNodes语句。
发布于 2009-09-10 11:45:50
你得到一个异常而他没有得到可能有很多原因,这些原因很可能与空字符的位置有关。根据他的堆栈,他的Null字符似乎在XML的末尾,位置115227。可能之前的文本只是有效的XML,并且意外地在文件的末尾添加了额外的空字符。你的空字符放在哪里?
或者,他的空字符位于属性或元素中,并被视为文本的一部分。它还可能取决于XML是UTF-8、UTF-16或其他编码类型。要考虑的变量太多了。
当NULL字符在末尾时,整个文件恰好是一个漂亮的、以null结尾的字符串。不过,正如您所说,奇怪的是,它被认为是一个未处理的异常,而它却在try-except块中……
有一些关于捕获未处理异常的interesting reading here,但它不能解释为什么会发生这些异常。
但如果非要我猜的话。在XML类后面有一堆非托管代码。由于NULL字符,此非托管代码会变得混乱,并且在发布时会产生错误。对SelectNodes()的调用将触发验证,并发现错误,因此将引发该错误。系统开始处理异常处理程序,但它会首先尝试释放xDoc,因为它不会在异常块内部或之后使用。这释放了非托管代码,但非托管代码仍然是混乱的,因此它再次引发异常。这将阻止Catch处理异常。您可以通过在Catch语句之后添加第二个xDoc.Load()来测试这一点,这将防止在Catch语句之前释放xDoc。
不过,这只是个猜测。在我看来,这是一个.NET的bug。
https://stackoverflow.com/questions/1404766
复制相似问题