1

XmlSchemaシングルトンとしてインスタンス化された があります。

public static XmlSchema MessageSchema
{
    get
    {
        lock (MessageSchemaLock)
        {
            // If this property is not initialised, initialise it.
            if (messageSchema == null)
            {
                // Read XSD from database.
                string xsd = Database.Configuration.GetValue("MessageBaseXsd");
                using (TextReader reader = new StringReader(xsd))
                {
                    messageSchema = XmlSchema.Read(reader, (sender, e) => {
                        if (e.Severity == XmlSeverityType.Error) throw e.Exception;
                    });
                }
            }
        }
        // Return the property value.
        return messageSchema;
    }
}
private static XmlSchema messageSchema = null;
private static readonly object MessageSchemaLock = new object();

このスキーマは、システムに入るすべてのドキュメントを検証するために使用されます。次のメソッドは検証を実行します。

/// <summary>
/// Validates the XML document against an XML schema document.
/// </summary>
/// <param name="xml">The XmlDocument to validate.</param>
/// <param name="xsd">The XmlSchema against which to validate.</param>
/// <returns>A report listing all validation warnings and errors detected by the validation.</returns>
public static XmlSchemaValidationReport Validate(XmlDocument xml, XmlSchema xsd)
{
    XmlSchemaValidationReport report = new XmlSchemaValidationReport();

    xml.Schemas.Add(xsd);
    xml.Validate((sender, e) => { report.Add(e); });
    xml.Schemas.Remove(xsd);

    return report;
}

XmlSchemaValidationReportリスト」といくつかのヘルパー メソッドが含まれており、オブジェクトを表示するものは何もありませんXmlSchema

複数のスレッドでメッセージを検証するとValidate、最初のいくつかのメッセージが処理された後にメソッドが失敗します。要素の 1 つが欠落していると報告されていますが、私にはそれがはっきりと見えています。私のテストでは、同じメッセージを複数回、それぞれ個別の として送信していますXmlDocument。プロパティがフィールドMessageSchemaを設定する唯一のコードであることを再確認しました。messageSchema

XmlSchema検証中に何らかの形で変更されていますか? 検証が失敗するのはなぜですか?

4

2 に答える 2

1

すべてのコメントとMiMoの回答に感謝します!彼らは私を解決策に導きました。

XmlSchema公のメンバーには電話をかけていませんが、XmlDocument.Validate()方法はそうです。オブジェクトには、XmlSchemaスレッドセーフではない状態情報が含まれています。

MessageShemaをスレッドごとのシングルトンに変更しました。

public static XmlSchema MessageSchema { ... }
[ThreadStatic]
private static XmlSchema messageSchema;

スキーマを私が望むよりも数回ロードしますが、現在は機能しています。これはMessageSchemaLock、値に複数のスレッドがアクセスできないため、を削除できることも意味します。

于 2012-08-31T00:34:41.433 に答える
1

XmlSchemaクラスはスレッドセーフではありません - 検証がそれを変更しようとするかどうかはわかりませんが、報告された問題からそうであるようです。あなたは試すことができます

public static XmlSchemaValidationReport Validate(XmlDocument xml, XmlSchema xsd) 
{ 
    XmlSchemaValidationReport report = new XmlSchemaValidationReport(); 

    lock (xsd) {
      xml.Schemas.Add(xsd); 
      xml.Validate((sender, e) => { report.Add(e); }); 
      xml.Schemas.Remove(xsd); 
    }
    return report; 
} 
于 2012-08-30T19:13:58.150 に答える