从XmlDocument对象读取是否线程安全?

4
我想知道是否可以安全地从XmlDocument对象使用SelectNodes()和SelectSingleNode()方法在多个线程中读取,MSDN称它们不能保证线程安全。如果SelectNodes()和SelectSingleNode()在多个线程中运行会出现问题,那么我可以使用适当的锁来避免任何问题吗?我已经设置了一个WCF服务,需要从数据库中获取一段XML并选择其中的一些信息。我想缓存XML以避免频繁访问数据库,但我担心线程安全和性能问题。有更好的方法来实现这个目标吗?谢谢
4个回答

5
这里有一个交易。如果文档说明实例方法没有保证线程安全,那么你最好注意一下。如果你决定在没有适当的同步机制的情况下在多线程场景中使用类,那么你需要 1)了解忽略文档的后果,2)准备好所有假设在未来版本中都将无效。即使对于似乎只读取内部状态的方法,这个建议也是有效的。
你怎么知道 SelectNodes 和 SelectSingleNodes 不修改内部变量?因为如果它们这样做,那么它们绝对不是线程安全的!现在,我恰好使用 Reflector 来查看内部结构,我可以看到它们并没有修改任何内部变量。但是,你怎么知道在将来的版本中不会改变呢?
现在,既然我们知道实际上 SelectNodes 和 SelectSingleNodes 不修改类的内部状态,那么它们可能是线程安全的操作,尽管有警告,但前提是以下条件满足:
- 在 XmlDocument 初始化后从未调用除 SelectNodes 或 SelectSingleNode 以外的任何其他方法。因为我没有检查 XmlDocument 类的所有方法,所以我不能说哪些方法修改类的内部状态,哪些方法不会,因此我会认为除了刚刚提到的 2 种方法之外的所有方法都有可能破坏你无锁使用该类的方法。 - 在另一个线程上调用 SelectNodes 或 SelectSingleNodes 之前,必须在一个线程上初始化 XmlDocument 并创建一个显式或隐式的内存屏障。我应该指出,会为你隐式地创建一个内存屏障作为得到多线程环境设置的结果。但是,我可以想到一些微妙的情况会导致这种方法失效。 我的建议……字面理解文档中的警告,并使用适当的同步机制。

2

如果您要读取/写入XML文档,为了避免竞争条件,需要同步这两个操作。如果您关心性能(谁不关心?),那么ReaderWriterLockSlim可能比锁定更好。


我不需要修改实际的xml,所以我不关心对其进行写操作,只需从中读取。但是,在创建XmlDocument并将其分配给我的静态变量时,我需要进行锁定。我会研究一下ReaderWriterLockSlim,虽然我不太熟悉它。 - Tallek
1
你应该关注编写代码,因为XML文档不会自己神奇地填充。如果在你填充它的同时有人试图从中读取,那么他将遇到竞争条件。 - Darin Dimitrov

0

SelectNodes / SelectSingleNode 应该是安全的(它们只读取数据)。当然,您需要将它们与任何实际修改 XML 的方法同步。


0

在调用createInstance时,您也可以使用MsXml FreeThreadedDOMDocument模型,而不是传统的DomDocument。

请注意,根据本文所述,FreeThreadedDOMDocument比传统的DomDocument慢7倍或10倍。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接