Memory 导致内存泄漏的通用数据读取器

Memory 导致内存泄漏的通用数据读取器,memory,memory-leaks,sqldatareader,Memory,Memory Leaks,Sqldatareader,我在读取sql语句时创建了一个通用方法,但每当我执行select查询并在读取时使用时,就会出现内存泄漏 示例查询: public CMItemPackagingType GetItemPackagingType(int itemID) { try { List<CommandParameter> param = new List<CommandParameter>()

我在读取sql语句时创建了一个通用方法,但每当我执行select查询并在读取时使用时,就会出现内存泄漏

示例查询:

    public CMItemPackagingType GetItemPackagingType(int itemID)
    {  
        try
        {               
            List<CommandParameter> param = new List<CommandParameter>();
            StringBuilder sb = new StringBuilder();
            using (BaseConnection db = new BaseConnection())
            {
                sb.Append("SELECT RATIO, PACKAGING_TYPE_CODE FROM ITEM_PACKAGING_TYPE WHERE ROUND_UP = 0.01 AND ITEM_ID = @itemID");

                param.Add(new CommandParameter("@itemID", itemID));
                using (var rs = db.ExecSQL(sb.ToString(), param.ToArray()))
                {
                    CMItemPackagingType cmItemInfo = new CMItemPackagingType();

                    while (rs.Read())
                    {
                        CMItemPackagingType list = new CMItemPackagingType();
                        if (!rs.IsDBNull(0))
                            list.Ratio = Convert.ToInt32(rs.GetValue(0));
                        if (!rs.IsDBNull(1))
                            list.PackagingTypeCode = rs.GetValue(1).ToString();

                        cmItemInfo.ItemPackagingTypeList.Add(list);
                    }
                    return cmItemInfo;
                }        
            }       
        }
        catch (Exception ex)
        {                
            GlobalFramework.HandleException(ex);
        }
        return null;
    }       
public cmitempackingtype getitempackingtype(int-itemID)
{  
尝试
{               
列表参数=新列表();
StringBuilder sb=新的StringBuilder();
使用(BaseConnection db=new BaseConnection())
{
sb.追加(“从项目包装类型中选择比率、包装类型代码,其中四舍五入=0.01,项目标识=@itemID”);
参数Add(新的CommandParameter(“@itemID”,itemID));
使用(var rs=db.ExecSQL(sb.ToString(),param.ToArray())
{
CMItemPackagingType cmItemInfo=新的CMItemPackagingType();
while(rs.Read())
{
CMItemPackagingType列表=新的CMItemPackagingType();
如果(!rs.IsDBNull(0))
list.Ratio=Convert.ToInt32(rs.GetValue(0));
如果(!rs.IsDBNull(1))
list.PackagingTypeCode=rs.GetValue(1).ToString();
cmItemInfo.ItemPackageTypeList.Add(列表);
}
返回cmItemInfo;
}        
}       
}
捕获(例外情况除外)
{                
全局框架.手柄异常(ex);
}
返回null;
}       
通用阅读器:

public DbDataReader ExecSQL(string sqlStmt, CommandParameter[] param)
    {

            List<MySqlParameter> p = ParameterMySql(param);
            _mySqlConn = new MySqlConnection(szConnect);
            if (_mySqlConn.State == ConnectionState.Open)
            {
                _mySqlConn.Close();
            }
            _mySqlConn.Open();
            _mySqlComm = new MySqlCommand(sqlStmt, _mySqlConn);
            _mySqlComm.Parameters.AddRange(p.ToArray());
            MySqlDataReader reader = _mySqlComm.ExecuteReader();

            return reader;

    }
public DbDataReader ExecSQL(字符串sqlStmt,CommandParameter[]param)
{
列表p=参数mySQL(参数);
_mySqlConn=新的MySqlConnection(szConnect);
if(_mySqlConn.State==ConnectionState.Open)
{
_mySqlConn.Close();
}
_mySqlConn.Open();
_mySqlComm=新的MySqlCommand(sqlStmt,_mySqlConn);
_mySqlComm.Parameters.AddRange(p.ToArray());
MySqlDataReader=_mySqlComm.ExecuteReader();
返回读取器;
}

我假设BaseConnection是围绕SqlConnection的包装,mySqlConn是BaseConnection的一个实例。我怀疑问题在于您正在ExecSQL中打开和关闭连接,同时有一个关于BaseConnection的using语句创建了此泄漏。我将通过正确放置using语句来重构代码,以确保正确处理对象和释放资源

示例

        var query = "YOUR QUERY";

        using (var connection = new SqlConnection("YOUR CONNECTION STRING"))
        {
            using (var command = new SqlCommand(query, connection))
            {
                await connection.OpenAsync();

                using (var reader = await command.ExecuteReaderAsync())
                {
                    if (reader != null)
                    {
                        while (await reader.ReadAsync())
                        {
                            // your logic
                        }
                    }
                } // reader closed and disposed up here
            } // command disposed here
        } //connection closed and disposed here
    }
还要注意我是如何使用ADO.NET方法的异步版本的。异步命令对于实现规模、吞吐量和延迟至关重要


我建议您不要试图开发一个通用数据读取器,而是自己编写所有的样板ADO.NET代码。

我假设BaseConnection是围绕SqlConnection的包装,mySqlConn是BaseConnection的一个实例。我怀疑问题在于您正在ExecSQL中打开和关闭连接,同时有一个关于BaseConnection的using语句创建了此泄漏。我将通过正确放置using语句来重构代码,以确保正确处理对象和释放资源

示例

        var query = "YOUR QUERY";

        using (var connection = new SqlConnection("YOUR CONNECTION STRING"))
        {
            using (var command = new SqlCommand(query, connection))
            {
                await connection.OpenAsync();

                using (var reader = await command.ExecuteReaderAsync())
                {
                    if (reader != null)
                    {
                        while (await reader.ReadAsync())
                        {
                            // your logic
                        }
                    }
                } // reader closed and disposed up here
            } // command disposed here
        } //connection closed and disposed here
    }
还要注意我是如何使用ADO.NET方法的异步版本的。异步命令对于实现规模、吞吐量和延迟至关重要

我建议您不要试图开发一个通用的数据读取器,而是自己编写所有的样板ADO.NET代码