Как разорвать петлю в случае какой-то ошибки поймали - PullRequest
1 голос
/ 09 января 2012

Q:

Я хочу разорвать цикл, если в событии было обнаружено какое-то исключение.

Код:

XmlDocument x = new XmlDocument();
x.Load(targetFileName);

XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
settings.ValidationEventHandler += Handler;

settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null,System.Web.HttpContext.Current.Server.MapPath("~/importSchema/IntialSchema.xsd"));
settings.ValidationFlags =
     XmlSchemaValidationFlags.ReportValidationWarnings |
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation;

using (StreamReader str_reader = new StreamReader(targetFileName))
{

    using (XmlReader validatingReader = XmlReader.Create(str_reader, settings))
    {
        while (validatingReader.Read())
        {
            //I wanna to break this loop if there is some caught error .
        }
    }
}

private static void Handler(object sender, ValidationEventArgs e)
{

    if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
    {
        try
        {
            throw new Exception(
                 String.Format("Line: {0}, Position: {1} \"{2}\"",
                     e.Exception.LineNumber, e.Exception.LinePosition, e.Exception.Message));
        }
        catch (Exception ee)
        {
            Common.ErrMappingForInformix.WriteLog(ee.Message);
            ScheduleForm sf = new ScheduleForm();
            sf.ShowStatus("Error,Invalid xml file", "error", "", 1);

        }

    }

}

# Редактировать 1:

XmlDocument x = new XmlDocument();
x.Load(targetFileName);

XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
settings.ValidationEventHandler += (senderValidation, ee) =>
{
    if (ee.Severity == XmlSeverityType.Error || ee.Severity == XmlSeverityType.Warning)
    {
        try
        {
            this.validationFailed = true;
            throw new Exception(
                 String.Format("Line: {0}, Position: {1} \"{2}\"",
                     ee.Exception.LineNumber, ee.Exception.LinePosition, ee.Exception.Message));
        }
        catch (Exception ex)
        {

            Common.ErrMappingForInformix.WriteLog(ex.Message);
            this.ShowStatus("Error", "error", "", 1);
        }

    }
};

settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null, System.Web.HttpContext.Current.Server.MapPath("~/importSchema/IntialSchema.xsd"));
settings.ValidationFlags =
     XmlSchemaValidationFlags.ReportValidationWarnings |
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation;

using (StreamReader str_reader = new StreamReader(targetFileName))
{

    using (XmlReader validatingReader = XmlReader.Create(str_reader, settings))
    {
        while (validatingReader.Read())
        {
            //Loop through the document
            if (validationFailed)
            {
                break;
            }

        }
    }
}

Он прерывает цикл, но не выполняет обработчик событий.

Ответы [ 2 ]

2 голосов
/ 09 января 2012

Вы можете установить флаг, чтобы указать, что есть ошибка в методе Handler, затем обнаружить этот флаг и использовать break;, если он установлен.

В этом случае может быть лучше использоватьвстроенный анонимный делегат для обработчика проверки, поэтому вам не нужно добавлять новую переменную-член в класс, содержащий методы.(Добавление переменной-члена не так уж и плохо, если класс only работает с чтением / проверкой XML)

Edit: анонимный встроенный делегат означает, что вы можете добавить обработчик событий, который не имеетбыть в отдельном методе, в основном.Например:

bool validationFailed = false; // outside of the handler
settings.ValidationEventHandler += (sender, e) =>
{
    if (e.Severity == XmlS....
    // set validationFailed = true; in here to signal failure
};

// then detect validationFailed being true to know if/when to break;
1 голос
/ 09 января 2012

Я бы просто выбросил исключение в обработчик и прервал поток управления при его перехвате.Однако также избегайте использования слишком общих типов исключений: лучше использовать пользовательское исключение:

class XmlValidationFailedException : Exception {
   public XmlValidationFailedException(string message, Exception innerException) : base(message, innerException) {}

   // as per Kieren's comment, make sure this exception type is defined according to best practices
}


private static void Handler(object sender, ValidationEventArgs e)
{

    if (e.Severity == XmlSeverityType.Error || e.Severity == XmlSeverityType.Warning)
    {
        string message = String.Format("Line: {0}, Position: {1} \"{2}\"",
                     e.Exception.LineNumber, e.Exception.LinePosition, e.Exception.Message)

        throw new XmlValidationFailedException(message);
    }

Тогда ваш цикл может выглядеть примерно так:

try
{
   while (validatingReader.Read())
   {
       // do logic
   }
}
catch (XmlValidationException ex)
{
    // handle the error (log, show, ...) 
    return;
}
...