旧版系统:此代码是否存在某些数据库连接泄漏的可能?

时间:2018-07-04 15:47:17

标签: c# .net enterprise-library

我们拥有使用Microsoft的Microsoft.Practices.EnterpriseLibrary库的旧系统:

一种方法如下:

  try
    {   
        IDataReader dr = DB.ExecuteReader(storedProcedureName, param1, param2);

        try
        {
            dr.Read();
        }
        catch (Exception e)
        {
        }
        finally 
        {
            try
            {
                dr.Close();
            }
            catch (Exception)
            {
            }
        }              
    }          
    catch (Exception ex2)
    {
    }           

库文档: https://docs.microsoft.com/en-us/previous-versions/msp-n-p/bb748704(v=pandp.50)

声明“执行命令并返回一个IDataReader,通过该IDataReader可以读取结果。调用者有责任在完成后关闭阅读器。”

该行:

IDataReader dr = DB.ExecuteReader(storedProcedureName, param1, param2);

是否已包含在第二次尝试中?和第一次尝试被删除?这会产生一些泄漏吗?为什么?

3 个答案:

答案 0 :(得分:1)

虽然繁琐,但此代码不应造成数据读取器的内存泄漏。

但是,它可以这样写得更简单,更简短:

try
{
    using(var dr = DB.ExecuteReader(storedProcedureName, param1, param2))
    {
        dr.Read(); 
        // It should be probably be while(dr.Read()) { /* do something with the data */ }
    }
}
catch(Exception ex)
{
// Do something with the exception!
}

答案 1 :(得分:0)

  

您的代码没有任何泄漏

但是根据这位官员Microsoft docs

SqlDataReader.Close()

不抛出任何异常,这样您就可以摆脱内部try catch

try
{   
    IDataReader dr = DB.ExecuteReader(storedProcedureName, param1, param2);

    try
    {
        dr.Read();
    }
    catch (Exception e)
    {
    }
    finally 
    {
        dr.Close();
    }              
}          
catch (Exception ex2)
{
}

但是有效的方法是像这样使用使用

try
{
    using(var dr = DB.ExecuteReader(storedProcedureName, param1, param2))
    {
        dr.Read(); 
    }
}
catch(Exception ex)
{
}

答案 2 :(得分:-1)

您可以考虑使用IDataReader而不是使用IDbCommand来使其安全并具有更好的灵活性。

 private static void ExecuteCommand(IDbConnection conn)
    {
        using (IDbCommand cmd = conn.CreateCommand())
        {
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "ProcedureName";
            IDataParameter param = cmd.CreateParameter();
            param.ParameterName = "@parameterName";
            param.Value = "parameter value";
            cmd.Parameters.Add(param);
            using (IDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    // get data from the reader
                }
            }
        }
    }

,即使您更喜欢将IDataReader与EnterpriseLibrary一起使用,也请始终考虑使用using语句,这会使代码更加安全并且不那么容易受到攻击。

            try
            {
                using (IDataReader dr = db.ExecuteReader(cmd))
                {
                    while (dr.Read())
                    {
                        // do something with the data
                    }
                }
            }
            catch (Exception e)
            {
                // exception handling
            }

希望有帮助。 :)