调用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应用程序中执行。
答案 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?。您可能想重新考虑这种缓存策略是否有意义。