Что я могу сделать, чтобы перестать получать ошибку пула подключений - PullRequest
0 голосов
/ 24 апреля 2020

Я довольно часто получаю следующую ошибку:

Npg sql .NpgsqlException: 'Пул соединений исчерпан, либо увеличьте MaxPoolSize (в настоящее время 100) или Timeout (в настоящее время 15 секунд)'

Затем я искал возможные причины и решения здесь и обнаружил, что должен применять заявление using. Поэтому я просмотрел весь свой код и сделал это.

Однако я продолжаю получать эту ошибку, когда тестирую кнопку, которая получает информацию из моей базы данных, выполняет некоторые вычисления и записывает результаты в нескольких текстовых полях. Обычно он вылетает в пятый раз, когда я щелкаю по нему. Вот фрагмент кода:

        private void CalcTemp(Cable cable)
        {
            string sqlString = "Server=172.19.2.40; Port=5432; User Id=postgres; Password=password; Database=PROLIG;";
            using (NpgsqlConnection sqlCon = new NpgsqlConnection(sqlString))
            {
                string cmdString = @"SELECT tempamb, elevmaxonan, elevmaxonaf, elevmaxonaf2, topoil1_2, topoil1_4, especial1factor, especial1topoil,
                                especial2factor, especial2topoil, especial3factor, especial3topoil, especial4factor, especial4topoil, 
                                especial5factor, especial5topoil, especial6factor, especial6topoil FROM correntes WHERE prolig_ofs_id = @id;";
                NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon);
                sqlCmd.Parameters.AddWithValue("id", StartOF.MyOF.id);
                NpgsqlDataAdapter sqlDa = new NpgsqlDataAdapter(sqlCmd);
                DataTable dt = new DataTable();
                sqlDa.Fill(dt);

                //does calculation

             }

Есть мысли о том, почему это происходит и как это исправить?

Большое спасибо.

1 Ответ

3 голосов
/ 24 апреля 2020

Просто добавьте использование к вашей команде создания:

using (NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon)) 
{

Хорошей практикой является удаление всех объектов, которые реализуют IDisposable. Поскольку ваша команда не удаляется вовремя, ваше соединение не закрывается и не возвращается в пул. Утилизация требует много вещей, которые должны быть выполнены напрямую (или с помощью).

    protected override void Dispose(bool disposing)
    {
        if (State == CommandState.Disposed)
            return;

        if (disposing)
        {
            // Note: we only actually perform cleanup here if called from Dispose() (disposing=true), and not
            // if called from a finalizer (disposing=false). This is because we cannot perform any SQL
            // operations from the finalizer (connection may be in use by someone else).
            // We can implement a queue-based solution that will perform cleanup during the next possible
            // window, but this isn't trivial (should not occur in transactions because of possible exceptions,
            // etc.).
            if (_prepared == PrepareStatus.Prepared)
                _connector.ExecuteBlind("DEALLOCATE " + _planName);
        }
        Transaction = null;
        Connection = null;
        State = CommandState.Disposed;
        base.Dispose(disposing);
    }

Поэтому вам нужен следующий код:

private void CalcTemp(Cable cable)
{
    string sqlString = "Server=172.19.2.40; Port=5432; User Id=postgres; Password=password; Database=PROLIG;";
    using (NpgsqlConnection sqlCon = new NpgsqlConnection(sqlString))
    {
        string cmdString = @"SELECT * FROM correntes WHERE prolig_ofs_id = @id;";
        using (NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon))
        {
            sqlCmd.Parameters.AddWithValue("id", StartOF.MyOF.id);
            NpgsqlDataAdapter sqlDa = new NpgsqlDataAdapter(sqlCmd);
            DataTable dt = new DataTable();
            sqlDa.Fill(dt);    
            //does calculation
        } //end using command (calls dispose on command, even if exception happens)
    } //end using connection (calls dispose on connection object, even if exception happens)
}

Следующий совет - не используйте Таблицы данных в случае большого количества данных. Вместо этого используйте DataReader.

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