【问题标题】:Catch exits after only one exceptionCatch 仅在一个异常后退出
【发布时间】:2012-09-02 13:36:21
【问题描述】:

在下面显示的 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。

【问题讨论】:

  • 你说你在循环,但我没有看到任何循环结构。
  • @Ikke:循环在这个函数之外。循环中的每个单词都会调用此函数

标签: c# append try-catch stringbuilder


【解决方案1】:

您没有显示badData 的声明位置。但是,每次调用 catch 块时,都会将 badData 重置为新的 StringBuilder - 这意味着它的旧实例(以及其中保存的任何值)都将被丢弃。如果您在 catch 块中删除此行:

badData = new StringBuilder();

你可能会更接近你想去的地方。

当您在执行此操作后最终出现空指针异常时,您需要确保将 badData 实例化为 = new StringBuilder();(正如您所拥有的那样),无论您已经声明了它 - IE,作为一个实例方法之外的变量。

【讨论】:

    【解决方案2】:

    在这种普通情况下,您确实不应该使用 try/catch 和异常机制来确定数据的有效性。这就是为什么它被称为“异常”的原因,因为它旨在处理可能导致程序崩溃的异常情况。如果你认为你的输入有一定比例是无效的,那就做一个普通的逻辑测试吧。

     if (valid(word) {function(word);} else {addToErrorList(word);} 
    

    【讨论】:

      【解决方案3】:

      您每次都在 catch 块中设置 badData = new StringBuilder();。所以,它确实被抓了 3 次,但你只看到 StringBuilder 中的最后一个坏词

      【讨论】:

        【解决方案4】:

        如果您希望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对象异常被捕获(因此所有错误都将被附加,而不仅仅是最后一个)。

        【讨论】:

          【解决方案5】:

          SQL 访问代码非常脆弱,我猜这就是原因,但关键是,您的异常处理不够充分,因为您只捕获 InvalidOperationException。在 Exception 类型的末尾添加另一个捕获,以查找早期轰炸的原因。 (正如 ziesemer 所说,停止重新初始化 sb。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-09-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多