Утечка памяти в коде C # - PullRequest
0 голосов
/ 29 августа 2018

У меня есть фрагмент кода, который каждую минуту отправляется в базу данных, чтобы проверить, есть ли какой-либо отчет, который нужно запустить, и если он есть, он его запускает.

Проблема в том, что при инициации моего объекта в классе базы данных возникает утечка памяти. Если я смотрю на задание mgr "Пользовательский объект", увеличиваемое на 5 каждый раз, когда отмечаем выполнение кода.

private void ReportRunTimer_Tick(object sender, EventArgs e)
        {
            DataConnection dataConnection = new DataConnection(); *<-- when executing this line User Object increasing.*
            try
            {
                reportsToRun = dataConnection.GetListOfTheReportForReportRunTick();
                if (reportsToRun.Count > 0)
                    foreach (string report in reportsToRun)
                    {
                        logs("Starting Automatic report generatin", "Successful");
                        Thread TicketReportMethodThread = new Thread(() => GenerateReport(report, 1));
                        TicketReportMethodThread.Start();
                    }
                dataConnection = null;
            } catch (Exception ex)
            {
                logs("Starting Automatic report generatin failed: " +ex.ToString(), "Error");
            }
            finally
            {
                reportsToRun.Clear();
            }
        }

Класс DataConnection

public List<string> GetListOfTheReportForReportRunTick()
{
    List<string> RepoerList = new List<string>();
    connString = "Server=xxx;Port=xxx;Database=xxx;Uid=xxx;password=xxxx;SslMode=none";
    using (MySqlConnection mySqlConnection = new MySqlConnection(connString))
    {
        try
        {
            MySqlCommand mySqlCommand = mySqlConnection.CreateCommand();
            mySqlCommand.CommandText = "SELECT reportname FROM reports WHERE nextruntime < NOW()";
            mySqlConnection.Open();
            MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();

            while (mySqlDataReader.Read())
            {
                RepoerList.Add(mySqlDataReader["reportname"].ToString());
            }

        }
        catch (MySqlException ex)
        {
            hd.logs("Failed to get reports with reportstorun_tick Error: " + ex.ToString(), "Error");
            mySqlConnection.Close();
        }
        finally
        {
            mySqlConnection.Close();
            mySqlConnection.Dispose();
        }
    }
    return RepoerList;
}

DataConnection dataConnection = new DataConnection(); используется еще в нескольких местах, и это единственное, что вызывает проблему.

Если я заменю код в приватном void ReportRunTimer_Tick на код из открытого списка GetListOfTheReportForReportRunTick (), как показано ниже. Вопрос больше не существует, есть идеи?

private void ReportRunTimer_Tick(object sender, EventArgs e)
{
    List<string> reportsToRun = new List<string>();
    try
    {
        connString = "Server=xxx;Port=xxx;Database=xxx;Uid=xxx;password=xxxx;SslMode=none";
        using (MySqlConnection mySqlConnection = new MySqlConnection(connString))
        {
            try
            {
                MySqlCommand mySqlCommand = mySqlConnection.CreateCommand();
                mySqlCommand.CommandText = "SELECT reportname FROM reports WHERE nextruntime < NOW()";
                mySqlConnection.Open();
                MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader();

                while (mySqlDataReader.Read())
                {
                    reportsToRun.Add(mySqlDataReader["reportname"].ToString());
                }



                if (reportsToRun.Count > 0)
                    foreach (string report in reportsToRun)
                    {
                        logs("Starting Automatic report generatin", "Successful");
                        Thread TicketReportMethodThread = new Thread(() => GenerateReport(report, 1));
                        TicketReportMethodThread.Start();

                    }
            }
            catch (MySqlException ex)
            {
                logs("Failed to get reports with reportstorun_tick Error: " + ex.ToString(), "Error");
                mySqlConnection.Close();
            }
            finally
            {
                mySqlConnection.Close();
                mySqlConnection.Dispose();
            }
        }

    }
    catch (Exception ex)
    {
        logs("Starting Automatic report generatin failed: " + ex.ToString(), "Error");
    }
    finally
    {
        reportsToRun.Clear();

    }

}

Проблема вызвана

DataConnection dataConnection = new DataConnection(); *<-- when executing this line User Object increasing.*
reportsToRun = dataConnection.GetListOfTheReportForReportRunTick();

Но я не могу понять, почему.

1 Ответ

0 голосов
/ 29 августа 2018

Я думаю, что утечка памяти связана с тем, что вы не утилизируете свой MySqlDataReader. Вы можете сделать это, просто заключив его в оператор using, например:

using(MySqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader()){
    while (mySqlDataReader.Read())
    {
        RepoerList.Add(mySqlDataReader["reportname"].ToString());
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...