c# - 我该怎么做才能停止出现连接池错误

标签 c# postgresql

我经常遇到以下错误:

Npgsql.NpgsqlException:“连接池已耗尽,请提高 MaxPoolSize(当前为 100)或超时(当前为 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

             }

对于为什么会发生这种情况以及如何解决它有什么想法吗?

非常感谢。

最佳答案

只需将 using 添加到您的命令创建中即可:

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

处置所有实现 IDisposable 的对象是一个很好的做法。 由于您的命令没有及时处理,因此您的连接没有关闭并返回到池中。 dispose 上有很多东西必须直接执行(或使用)。

    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。

关于c# - 我该怎么做才能停止出现连接池错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61416376/

相关文章:

c# - 转换派生类型和动态最佳实践

c# - ASP.net WebForms - 在标记中使用 GetRouteUrl

c# - WPF 列表框在拖动时自动滚动

c# - 需要多个相似字符串的正则表达式

ruby-on-rails - 延迟作业 : can't run rake jobs:work

c# - 高效的数据表分组依据

java - 从 PostgreSQL 时间戳值格式化 java.time Instant 值

ruby-on-rails - 卡皮斯特拉诺 "No tty present and no askpass program specified"

ruby - 未初始化的常量 ActiveRecord::ConnectionAdapters::ConnectionManagement

sql - PSQL 连接 - 列 "table.column"不存在