[英]Why XmlDocument.Load(XmlReader reader) calls XmlNode.RemoveAll()?
調用SimpleClass.LoadXml時,引發以下異常
你調用的對象是空的。 在System.Xml.XmlNode.RemoveChild(XmlNode oldChild)在System.Xml.XmlNode.RemoveAll()在System.Xml.XmlDocument.Load(XmlReader reader)
SimpleClass
看起來像這樣
public static class SimpleClass
{
static XmlDocument _myXmlDocu = new XmlDocument();
/// <summary>
/// Method to load embedded XML data file from assembly.
/// </summary>
private static void LoadXml()
{
Assembly asm = Assembly.GetExecutingAssembly();
XmlTextReader reader = new XmlTextReader(asm.GetManifestResourceStream("MyNameSpace.data.xml"));
_myXmlDocu.Load(reader);
}
}
我不明白為什么XmlNode.RemoveAll()
被調用時,我打電話_myXmlDocu.Load(reader)
?
該代碼在IIS上的ASP.NET WebForms應用程序中執行。
XmlDocument.Load()
調用XmlNode.RemoveAll()
以便在讀取XML文件之前從XML文檔中刪除所有現有數據,因為Load()
用新讀取的XML數據替換了XmlDocument
的當前內容,而不是合並或追加他們。
更好的問題是,為什么RemoveAll()
引發異常? 最可能的原因是由於多線程:進程中的兩個線程正在嘗試一次初始化_myXmlDocu
靜態變量,並且彼此步進。 (根據docs , 不保證XmlDocument
實例成員是線程安全的)。 看來您試圖將清單資源流中的XML作為單個實例緩存在內存中,只能讀取一次。 如果是這樣,則應按照此處的說明以線程安全的方式初始化緩存: 在C#中實現Singleton Pattern 。
例如,這是在SimpleClass
緩存XML資源的一種簡單的線程安全方法。 它將資源加載到該類的靜態構造函數中:
public static class SimpleClass
{
const string resourceName = "MyNameSpace.data.xml";
static XmlDocument _myXmlDocu = null;
static SimpleClass()
{
_myXmlDocu = new XmlDocument();
Assembly asm = Assembly.GetExecutingAssembly();
using (var reader = new XmlTextReader(asm.GetManifestResourceStream(resourceName)))
{
_myXmlDocu.Load(reader);
}
}
public static XmlDocument GetResourceData()
{
return _myXmlDocu;
}
}
這是第一次加載XML資源文件,這是第一次使用SimpleClass
的靜態方法或屬性。 它對應於鏈接文章中單例模式的“第四版”。
如果您的SimpleClass
實際上並不簡單,並且具有許多不相關的靜態屬性和方法,要求您將XML的加載推遲到實際使用之前,請考慮在鏈接的文章中使用該模式的第五個或第六個版本。
順便說一句,盡管對XmlDocument
寫操作(如Load()
)絕對不是線程安全的,但未將讀操作記錄為線程安全的。 請參見從XmlDocument對象線程讀取是否安全? 進行討論。 您可能想重新考慮這種緩存策略是否有意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.