2009-11-09 86 views
3

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

回答

5

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

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

现在,由于我们实际上知道SelectNodes和SelectSingleNodes不会修改类的内部状态,因此尽管出现警告,但只有在以下条件适用的情况下,它们才可以用于多线程操作。

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

我的建议...从字面上理解文档中的警告并使用适当的同步机制。

0

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

2

正如您要写入/从XML文档读取/ /如果您不想运行竞争条件需要同步这两个操作。如果你关心性能(谁不关心?)ReaderWriterLockSlim可能比锁定更好。

+0

我不需要修改实际的XML,所以我不关心写入它,只是读它。当我创建XmlDocument并将其分配给我的静态变量时,我需要锁定它。虽然我不熟悉ReaderWriterLockSlim。 – Tallek 2009-11-09 20:03:54

+1

您应该关注编写,因为XML文档本身不会自动填充,并且如果您在填写时有人试图从中读取它,那么他将遇到竞争状况。 – 2009-11-09 20:06:34

0

当您调用createInstance时,您还可以使用MsXml FreeThreadedDOMDocument模型而不是古典DomDocument。

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