调用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()
用XmlDocument
新读取的XML数据替换的当前内容,而不是合并或附加它们。
更好的问题是,为什么会RemoveAll()
引发异常?最可能的原因是由于多线程:您进程的两个线程正在尝试_myXmlDocu
一次初始化您的静态变量,并且彼此步进。(据文档,实例成员XmlDocument
都不能保证是线程安全的)。看来您试图将清单资源流中的XML作为单个实例缓存在内存中,只能读取一次。如果是这样,则应按照此处的说明以线程安全的方式初始化缓存:在C#中实现Singleton Pattern。
例如,这是一种在内部缓存XML资源的简单线程安全方法SimpleClass
。它将资源加载到该类的静态构造函数中:
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直到实际使用XML,请考虑在链接的文章中使用该模式的第五个或第六个版本。
顺便说一句,尽管对XmlDocument
(如Load()
)的写入操作绝对不是线程安全的,但也未将读取操作记录为线程安全的。请参见从XmlDocument对象线程读取是否安全?进行讨论。您可能需要重新考虑此缓存策略是否有意义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句