Catch завершает работу только после одного исключения

В моем примере try/catch, показанном ниже, приложение перебирает слова, введенные пользователем в текстовое поле. (Я уже убедился, что эта часть работает.) Когда он перебирает слова, он передает каждое слово функции, указанной ниже.

private string runQuery(string data)
    {
        // Step 1 - Declare the query and parameters
        SqlCeConnection connection = new SqlCeConnection(@"Data Source=keywordDB.sdf");
        SqlCeCommand cmd = new SqlCeCommand("SELECT abbrev, description FROM abbreviations WHERE abbrev LIKE @abbrev", connection);
        cmd.Parameters.AddWithValue("@abbrev", data);
        SqlCeDataReader reader;

        try
        {
            // Step 2 - Opens the connection
            connection.Open();

            // Step 3- Execute query and assign the data to abbrevQueryResult and results
            reader = cmd.ExecuteReader();
            reader.Read();
            abbrevQueryResult = reader[0].ToString();
            results = reader[1].ToString();

            // Step 4 compare abbrevQueryResult to data entered by user in textbox
            if (abbrevQueryResult.ToLower().Equals(data.ToLowerInvariant()))
            {
                returnResults.Append(" " + results + ",");
            }
        }

        catch (InvalidOperationException e)
        {
            badData = new StringBuilder();
            badData.Append(" " + data);
        }

        finally
        {
            if (connection != null)
            {
                connection.Close();
            }
        }

        return returnResults.ToString();
    }

Я заметил, что если я ввожу 6 слов, 3 из которых должны работать нормально, а 3 должны быть пойманы оператором catch, то оператор catch поймает только самое последнее. Любая идея, почему он улавливает только одно из слов? Я бы хотел, чтобы он перехватил их всех и добавил в StringBuilder badData.


person pallasmedia    schedule 09.09.2012    source источник
comment
Вы говорите, что зацикливаетесь, но я не вижу никакой конструкции цикла.   -  person Ikke    schedule 09.09.2012
comment
@Ikke: цикл находится вне этой функции. Эта функция вызывается для каждого слова внутри цикла.   -  person DarK    schedule 09.09.2012


Ответы (5)


Вы не показываете, где объявлено badData. Однако каждый раз, когда вызывается ваш блок catch, вы сбрасываете badData в новый StringBuilder, что означает, что его старый экземпляр (и любые содержащиеся в нем значения) отбрасываются. Если вы удалите эту строку в блоке catch:

badData = new StringBuilder();

вы, вероятно, будете ближе к тому, где вы хотите быть.

Когда после этого вы получите исключение с нулевым указателем, вам необходимо убедиться, что badData инстанцируется до = new StringBuilder(); (как у вас было) везде, где вы уже объявили его - т.е. как переменную экземпляра вне метода.

person ziesemer    schedule 09.09.2012

Вам действительно не следует использовать механизм try/catch и исключения для определения достоверности ваших данных в обычной ситуации, подобной этой. Вот почему это называется «исключением», потому что оно предназначено для обработки исключительных случаев, которые могут привести к сбою вашей программы. Если вы ожидаете, что какой-то процент вашего ввода будет неверным, то проведите для него обычную логическую проверку.

 if (valid(word) {function(word);} else {addToErrorList(word);} 
person Jeff D.    schedule 09.09.2012

Если вы хотите, чтобы badData содержало все ошибки, вы не можете инициализировать переменную в предложении catch, потому что тогда вы сбрасываете переменную для каждого перехваченного исключения. Если вы инициализируете его в другом месте, это может сработать.

Инициализация его в верхней части вашего класса:

public class MyClass {
     private StringBuilder badData = new StringBuilder();

     // Other code
}

Инициализация его в вашем конструкторе:

public class MyClass {
     private StringBuilder badData;

     public MyClass() {
          badData = new StringBuilder();
     }
}

Поступая таким образом, переменная будет существовать до тех пор, пока существует объект, а затем вам просто нужно удалить инициализацию в предложении catch, чтобы переменная не сбрасывалась в новый объект StringBuilder каждый раз, когда перехватывается исключение (и таким образом, будут добавлены все ошибки, а не только последняя).

person ba0708    schedule 09.09.2012

Вы устанавливаете badData = new StringBuilder(); каждый раз в блоке catch. Итак, он пойман 3 раза, но вы видите только последнее плохое слово в своем StringBuilder

person DarK    schedule 09.09.2012

Этот код доступа к SQL очень хрупок, и я предполагаю, что это причина, но дело в том, что ваша обработка исключений неадекватна, потому что вы перехватываете только InvalidOperationException. Добавьте еще одну ловушку в конце для типа Exception, чтобы найти причину преждевременного срабатывания бомбы. (И, как сказал ziesemer, перестаньте повторно инициализировать sb.)

person Reg Edit    schedule 09.09.2012