2017-08-14 67 views
0

根据MSDN,XmlSchemaSet类不保证是线程安全的。是否允许在多个XmlReader/XmlWriter对象之间共享XmlSchemaSet?

那么多个XmlReader对象可以创建一个对象引用一个XmlSchemaSet对象,并从多个线程并发使用一个​​对象?或者这是否意味着我需要创建一个新的​​对象,并在每次需要在后台处理新文档时为其分配一个新副本XmlSchemaSet

看起来像这样会很浪费。特别是因为XmlSchemaSet需要重新编译每个新文档的模式。

XmlWriter对象的答案是否一样?

当然,我不会在最初填充对象后修改XmlSchemaSet对象。在首次使用之前,我也会调用Compile方法。之后,它似乎似乎像一切应该是安全的,因为只有读取会执行,但我不知道。

+0

@ mjwills对不起,我离开电脑。是的,两个答案都证实了我害怕的事情:不要依赖这一点,即使可能多读者,零写作者场景可以工作。现在决定哪一个标记为接受... –

回答

2

如果它说它不是线程安全的,那么(合同上),你不能共享/并行使用它。

现在它可能工作。但微软明确表示,保证的工作。因此,即使它今天有效,如果下次升级.NET Framework时可能无法正常工作(例如)。

其它类型的不是线程安全的http://referencesource.microsoft.com/#System.Xml/System/Xml/Schema/XmlSchemaSet.cs(例如Hashtable)的使用将意味着我会强烈建议您不要跨线程使用XmlSchemaSet。在多个线程使用XmlSchemaSet如果你是可能是OK只是阅读(因为Hashtable支持多个阅读器,例如) - 但XmlSchemaSet在多个线程的工作是不是永久保证(即使今天它的工作)。

2

不是100%确定当前版本,但在.NET的开始,我遇到了这个问题。编译XmlSchema很可能会修改它(向其添加后编译信息)。验证已经编译好的程序很可能不会,但重点是:你不能依赖这个。

我从此以后的处理方式是(作为创建新模式的一种替代方法)将单例保存在类中并同步对它的访问。这意味着:不要直接或间接地发布对它的引用(例如通过XmlReader)。

通常我编写静态服务方法来将XML加载到XDocument或类似文件中。

+0

我知道编译会改变状态,这就是为什么我说我会在将模式集传递给任何其他线程之前编译。但我不明白你的提案如何避免这个问题。单例或静态类仍然需要创建XmlSchemaSet的副本,并为每次调用重新编译它,或者同步线程之间的访问。所以你要么增加额外的计算或失去并发性,这是使用多个线程的关键。 –

+1

我的意思是:在XML解析的问题上同步访问和丢失并发,但当然不适用于物化的例如后续处理。 'XDocument'。 – tinudu