try/catch块没有捕获异常

Sas*_*ash 0 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();
                    }
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

Mot*_*Azu 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Sash我仍然建议你应该返回IEnumerable而不是IList,它更健壮.这只是不必要的屈服. (2认同)