为什么XmlDocument.Load(XmlReader reader)调用XmlNode.RemoveAll()?

时间:2015-03-25 22:57:46

标签: c# asp.net xml

调用SimpleClass.LoadXml时,抛出以下异常

  

对象引用未设置为对象的实例。在   System.Xml.XmlNode.RemoveChild(XmlNode oldChild)at   System.Xml.XmlNode.RemoveAll()at   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应用程序中执行。

1 个答案:

答案 0 :(得分:1)

XmlDocument.Load()调用XmlNode.RemoveAll()以便在读取XML文件之前从XML文档中删除所有现有数据,因为Load() 替换了 {的当前内容{1}}使用新读取的XML数据,而不是合并或附加它们。

更好的问题是,为什么XmlDocument会抛出异常?最可能的原因是多线程:您的进程的两个线程正在尝试一次初始化RemoveAll()静态变量,并且互相踩踏。 (根据docs_myXmlDocu的实例成员保证是线程安全的。您似乎正在尝试将清单资源流中的XML作为单个实例缓存在内存中,只读取一次。如果是这样,您应该按照此处的说明以线程安全的方式初始化缓存:Implementing the Singleton Pattern in C#

例如,这是一种在XmlDocument内缓存XML资源的简单线程安全方法。它将资源加载到类的静态构造函数中:

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; } } 的静态方法或属性。它对应于&#34;第四版&#34;来自链接文章的单例模式。

如果您的SimpleClass实际上并不简单,并且有许多不相关的静态属性和方法,要求您推迟加载XML直到实际将要使用它,请考虑使用该模式的第五个或第六个版本链接的文章。

顺便说一句,虽然对SimpleClass(如XmlDocument)的写操作绝对不是线程安全的,但读操作也不是记录是线程安全的。有关讨论,请参阅Is reading from an XmlDocument object thread safe?。您可能想重新考虑这种缓存策略是否有意义。