Универсальный считыватель данных, вызывающий утечку памяти - PullRequest
1 голос
/ 28 октября 2019

Я создал универсальный метод в чтении оператора 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;

    }

1 Ответ

0 голосов
/ 30 октября 2019

Я предполагаю, что BaseConnection является оберткой вокруг SqlConnection, а _mySqlConn является экземпляром BaseConnection. Я подозреваю, что проблема в том, что вы открываете и закрываете соединение в ExecSQL, и в то же время у вас есть оператор using вокруг BaseConnection, создающий эту утечку. Я бы рефакторинг вашего кода с правильным размещением операторов использования для обеспечения правильного удаления объектов и освобождения ресурсов.

Пример

        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. Асинхронные команды имеют решающее значение для достижения масштаба, пропускной способности и задержки.

Я рекомендую использовать Dapper вместо попыток разработки универсального устройства чтения данных и написания всего стандартного кода ADO.NET самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...