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