2017-08-14 82 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