Синхронная проверка схемы XML?.NET 3.5

Я знаю, что могу проверить xml на схеме с помощью метода обратного вызова, например, следующим образом, но есть ли способ, который я могу сделать это синхронно, а не с помощью события?

Один из способов, по которым я думал, - установить логический флаг класса IsValidated = false, а затем вызовите xml.Validate(ValidationEventHandler). Обработчик событий установил IsValidated = true после его завершения. В то же время проверяйте цикл, пока флаг не будет установлен в true, а затем продолжите.

Это для .Net 3.5.

    public bool ValidateSchema(string xmlPath, string xsdPath)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        xml.Validate(ValidationEventHandler); 
    }

Хорошо, я сделал тест, и похоже, что xml.validate фактически ожидает завершения обратного вызова до того, как будет выполнен новый код.

В следующем примере MessageBox.Show( "После проверки" ); всегда происходит после выполнения myValidationEventHandler.

Я также прошел через код, чтобы проверить это.

Итак, я думаю, это делает мой вопрос не вопросом.

// load etc.
...

xmlValidate(myValidationEventHandler);

MessageBox.Show("After Validate");


    private void myValidationEventHandler(object sender, ValidationEventArgs e)
    {
        for (double i = 0; i < 100000; i++)
        {
            textBox1.Text = i.ToString();
            Application.DoEvents();
        }

    // do stuff with e
    }

Ответ 1

Вы можете указать null для ValidationEventHandler, чтобы метод Validate выдавал исключение.

    public bool ValidateSchema(string xmlPath, string xsdPath)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        try
        {
            xml.Validate(null);
        }
        catch (XmlSchemaValidationException)
        {
            return false;
        }
        return true;
    }

Ответ 2

Используйте ManualResetEventSlim.

Set() событие в обратном вызове и WaitOne() после вызова Validate().

Ответ 3

Я думаю, что M3NTA7 прав, что мы смотрим на это неправильно, когда беспокоимся о том, что он асинхронен.
Не забывайте, что вы не вызываете Validate() в асинхронном порядке, поэтому вы не покидаете поток.

Мы передаем адрес validationCallback в качестве цели, чтобы мы могли настраивать обработку любых ошибок из проверки.
Но этот процесс вызова делегата callback validation все происходит, я считаю синхронно внутри синхронного вызова Validate().:)

Итак, все это будет сделано, если Validate() вернется.

Ответ 4

Я бы передал функцию, которая делает то, что вам нужно, чтобы сделать, если Valid, тогда она вернется к ней после правильной проверки.

public void ValidateSchema(string xmlPath, string xsdPath, Action Success)
    {
        XmlDocument xml = new XmlDocument();
        xml.Load(xmlPath);

        xml.Schemas.Add(null, xsdPath);

        if( xml.Validate(ValidationEventHandler) ) Success();
    }