从XmlDocument对象线程读取安全吗?

时间:2009-11-09 19:09:35

标签: c# multithreading

我想知道我是否可以安全地从多个线程中使用SelectNodes()和SelectSingleNode()从XmlDocument对象读取而没有任何问题。 MSDN表示不保证它们是线程安全的。如果SelectNodes()和SelectSingleNode()确实存在从多个线程运行的问题,我可以使用正确的锁定来避免任何问题吗?我有一个WCF服务设置,需要从数据库中获取一大块xml并从这个xml中选择一些信息。我想缓存xml以避免频繁访问数据库,但我担心线程的安全性和性能。有没有更好的方法来做这个?感谢

4 个答案:

答案 0 :(得分:5)

这是交易。如果文档说实例方法不保证是线程安全的那么你最好注意一下。如果您决定在多线程场景中使用该类而没有适当的同步机制,那么您需要1)了解忽略文档的后果和2)为您的所有假设做好准备,以便在类的未来版本中失效。即使对于似乎只是阅读内部状态的方法,这个建议也是有效的。

你怎么知道SelectNodes和SelectSingleNodes不修改内部变量?因为如果他们这样做,他们绝对不是线程安全的!现在,我碰巧使用Reflector查看内部,我可以看到它们不会修改任何内部变量。但是,您如何知道未来的版本不会改变?

现在,因为我们实际上知道SelectNodes和SelectSingleNodes不会修改类的内部状态,所以它们可能对于多线程操作是安全的,尽管警告当且仅当以下条件适用时才会发出警告。< / p>

  • 在初始化XmlDocument之后,除了SelectNodes或SelectSingleNode之外,没有其他方法被调用。因为我没有检查过XmlDocument类的所有方法,所以我不能说出哪些方法修改了类的内部状态,哪些方法没有。因此我会考虑除了我提到的两种方法以外的所有方法锁定使用该类的方法。
  • 在一个线程上初始化XmlDocument之后,在另一个线程上调用SelectNodes或SelectSingleNodes之前,会创建显式或隐式内存屏障。我应该注意,由于获得多线程环境设置,很可能会隐式创建内存屏障。但是,我可以想到一些细微的情况会发生故障。

我的建议......按字面意思采用文档中的警告并使用适当的同步机制。

答案 1 :(得分:2)

当您要写入/读取XML文档时,如果您不想遇到竞争条件,则需要同步这两个操作。如果你关心性能(谁没有?),ReaderWriterLockSlim可能比锁定更好。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

当你调用createInstance时,你也可以使用MsXml FreeThreadedDOMDocument 模型而不是经典的DomDocument。

请注意,根据this article,FreeThreadedDOMDocument比传统的DomDocument慢7倍或10倍。