我在读取sql语句时创建了一个通用方法,但是每当执行选择查询并在读取时使用时,都会发生内存泄漏。
示例查询:
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 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;
}
我假设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代码时使用Dapper。