2009-09-10 75 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