2009-09-10 50 views
1

在阅读关于未处理的XmlException的this recent question时,我试图在.NET 2.0和3.5控制台应用程序中重现它。奇怪的未处理的XmlException行为

但是,在我的代码中,它的行为与预期的完全一样,XmlDocument.Load方法抛出一个XmlException,因为源xml文件包含一个NULL字符。

那么,为什么下面的代码中的Load语句(从该示例中),不抛出XmlException?更重要的是,为什么XmlException不是由围绕SelectNodes()方法调用的有效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); 
    } 

回答

2

如预期的那样,XmlDocument.Load总是抛出异常。

这只是有时调试器错误的行号。根据我的经验,错误地将下一行代码突出显示为异常的抛出者并不少见。

你可以在屏幕截图中看到:ASP错误页面正确显示XmlDocument.Load是投掷者,而不是SelectNodes语句。

+0

你看起来是正确的。我在Reflector中检查了Load和SelectNodes的实现,它只出现Load calls XmlLoader.LoadNode()(如堆栈跟踪所示)。因此,调试符号可能与显示的代码不同步。 – Ash 2009-09-10 14:16:00

1

可能有很多原因,你会得到一个异常而他没有,这很可能与NULL字符的位置有关。根据他的堆栈,他的Null字符看起来是位于XML末尾的位置115227.它可能是前面的文本只是有效的XML,并且在文件末尾添加了一个额外的NULL字符。你在哪里有你的空字符?

或者,他的NULL字符位于属性或元素内部,并被认为是文本的一部分。它也可能取决于XML是UTF-8,UTF-16还是其他编码类型。有太多的变数需要考虑。


当NULL字符结束时,整个文件恰好是一个很好的,以空字符结尾的字符串。不过,正如你所说,它被认为是一个未处理的异常,而它处于try-except块内部,这很奇怪......

关于捕获未处理的异常有一些interesting reading here,但它不能解释它为什么会发生。

但是,如果我必须猜测... XML类后面有一堆非托管代码。由于空字符,这个非托管代码会变得混乱,并会在释放时产生错误。对SelectNodes()的调用将触发验证并发现错误,从而引发错误。系统开始处理异常处理程序,但它首先尝试释放xDoc,因为它不在异常块内部或之后使用。这释放了非托管代码,但非托管代码仍然存在混淆,因此它会再次发生异常。这会阻止Catch处理异常。 您可以通过在Catch语句之后添加第二个xDoc.Load()来测试此操作,这将防止在捕获之前释放xDoc。

不过,这只是一个猜测......看起来.NET的bug对我来说。

+0

测试了一个120K文件。 XML内部的NULL引发,文档末尾的NULL在Load()或SelectNodes()中不会导致任何问题。但真正的问题是为什么当在显式处理XmlException的try块中调用SelectNodes()时,为什么XmlException被认为是未处理的? – Ash 2009-09-10 12:19:21