try / catch块没有捕获异常

时间:2014-07-27 09:44:10

标签: c# sqlite exception-handling

我遇到的问题是try / catch块没有捕获异常。问题发生在 command.ExecuteReader(),但它永远不会被捕获。我在调试模式下运行,并且已经尝试了一些关于调试器设置的建议选项,但没有用。

我想提一下我使用SQLite作为我的提供程序,我可以看到它抛出SQLiteException,但问题仍然存在。是否存在未捕获异常的特定情况? (除了StackOverflowException,ThreadAbortedException等...)

    public IEnumerable<dynamic> Query(string sql, params object[] parms)
    {
        try
        {
            return QueryCore(sql, parms);
        }
        catch (Exception ex)
        {
            throw new DbException(sql, parms, ex);
        }
    }

    private IEnumerable<dynamic> QueryCore(string sql, params object[] parms)
    {
        using (var connection = CreateConnection())
        {
            using (var command = CreateCommand(sql, connection, parms))
            {
                using (var reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        yield return reader.ToExpando();
                    }
                }
            }
        }
    }

我还想补充一点,如果我对数据库产生了正确的查询,我会得到结果,但是当我中断查询时,会抛出异常,但不会被捕获。

1 个答案:

答案 0 :(得分:5)

这是因为您使用yield关键字返回数据。 这使得数据实际数据方法仅在枚举其结果时才能运行。

您可能不希望这种情况发生,特别是因为如果结果被枚举两次(例如两个单独的foreach循环),数据将被读取两次。 您可以这样做以使枚举立即发生并捕获任何异常:

public IEnumerable<dynamic> Query(string sql, params object[] parms)
{
    try
    {
        return QueryCore(sql, parms).ToArray();
    }
    catch (Exception ex)
    {
        throw new DbException(sql, parms, ex);
    }
}

Yielding适用于获取项目需要一些时间的情况,并且您不希望在循环播放之前获取所有项目。所以另一个可能的解决方案,可能更好的代码的可读性(我认为不需要屈服)将是这样的:

public IEnumerable<dynamic> Query(string sql, params object[] parms)
{
    try
    {
        return QueryCore(sql, parms);
    }
    catch (Exception ex)
    {
        throw new DbException(sql, parms, ex);
    }
}

private IEnumerable<dynamic> QueryCore(string sql, params object[] parms)
{
    using (var connection = CreateConnection())
    {
        using (var command = CreateCommand(sql, connection, parms))
        {
            using (var reader = command.ExecuteReader())
            {
                var results = new List<dynamic>();
                while (reader.Read())
                {
                    results.Add(reader.ToExpando());
                }

                return results;
            }
        }
    }
}