c# - Sql 连接中的连接打开和关闭问题

标签 c# asp.net connection-pooling

找到许多解决方案,但没有一个解决方案适合我的场景。

问题: 我正在开发在 asp.net 下构建的在线软件。从过去几天开始,我的应用程序运行缓慢,有时甚至崩溃。当我尝试查找问题时,我发现连接池中有处于休眠模式的连接。我知道某些连接已打开但未正确关闭。在下面,我将向您展示我的 DBManager 文件。请检查它并给我建议,这可以帮助我正确打开和关闭我的连接。

注意:当用户快速使用应用程序时会抛出连接异常。 我的应用程序使用许多数据输入运算符,这些运算符速度很快。并一次又一次地在页面之间移动。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;

/// <summary>
/// Summary description for DBManager
/// </summary>
public class DBManager
{
    public static SqlConnection _connection;
    public static SqlCommand _command;
    public static SqlDataReader _reader;
    public static SqlDataAdapter _dataAdapter;
    public List<SqlParameter> Parameters = new List<SqlParameter>();
    public static string _connectionString = "DefaultConnectionString";
    SqlTransaction _sqlTransaction;
     
    public DBManager()
    {
        // TODO: Add constructor logic here
    }

    public DBManager(SqlTransaction sqlTransaction = null)
    {
        _sqlTransaction = sqlTransaction;
    }

    public DBManager(string connectionStringName, SqlTransaction sqlTransaction = null)
    {
        _connectionString = connectionStringName;
        _sqlTransaction = sqlTransaction;
    }

    public static string CreateConnection()
    {
        string ConnectionString = ConfigurationManager.ConnectionStrings[_connectionString].ConnectionString;
        _connection = new SqlConnection(ConnectionString);
        _connection.Open();
        return "0";
    }

    public static void CloseConnection()
    {
        _connection.Close();
        _connection.Dispose();
    }

    public void AddParameter(string parameterName, object value, SqlDbType sqlDbType, int size)
    {
            SqlParameter parameter = new SqlParameter(parameterName, sqlDbType, size);
            parameter.Value = value;

            Parameters.Add(parameter);      
    }

    public void AddParameter(string parameterName, object value, SqlDbType sqlDbType, int size,ParameterDirection parameterDirection)
    {
        SqlParameter parameter = new SqlParameter(parameterName, sqlDbType, size);
        parameter.Value = value;
        parameter.Direction = parameterDirection;
        Parameters.Add(parameter);
    }

    public void AddParameter(string parameterName, object value)
    {
        SqlParameter parameter = new SqlParameter(parameterName,value);
        Parameters.Add(parameter);
    }

    public int ExecuteNonQuery(string procedureName)
    {
        int result = 0;

        try
        {
           // if (CreateConnection() == "1") { return 0; }
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);
            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }
            _command.CommandType = CommandType.StoredProcedure;
            result = _command.ExecuteNonQuery();
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }

        return result;
    }

    public SqlDataReader ExecuteReader(string procedureName)
    {
        SqlDataReader reader;

        try
        {
            CreateConnection();
           // if (CreateConnection() == "1") { return reader=0; }
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }

            _command.CommandType = CommandType.StoredProcedure;
            reader = _command.ExecuteReader(CommandBehavior.CloseConnection);
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }
      
        return reader;
    }

    public DataSet ExecuteDataSet(string procedureName)
    {
        DataSet dataSet = new DataSet();

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);    
                }
                
            }

            _command.CommandType = CommandType.StoredProcedure;
            _dataAdapter = new SqlDataAdapter(_command);
            _dataAdapter.Fill(dataSet);
            CloseConnection();
            _command.Dispose();
            _dataAdapter.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _dataAdapter.Dispose();
            _command.Dispose();
            throw;
        }
           return dataSet;
    }

    public DataTable ExecuteDataTable(string procedureName)
    {
        DataTable dataTable = new DataTable();

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }
            }

            _command.CommandType = CommandType.StoredProcedure;
            _dataAdapter = new SqlDataAdapter(_command);
            _dataAdapter.Fill(dataTable);
            CloseConnection();
            _command.Dispose();
            _dataAdapter.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _dataAdapter.Dispose();
            _command.Dispose();
            throw;
        }
       
        return dataTable;
    }

    public string ExecuteScalar(string procedureName)
    {
        string result = "";

        try
        {
            CreateConnection();
            _command = new SqlCommand(procedureName, _connection);

            if (Parameters.Count != 0)
            {
                for (int i = 0; i < Parameters.Count; i++)
                {
                    _command.Parameters.Add(Parameters[i]);
                }

            }

            _command.CommandType = CommandType.StoredProcedure;
            result = _command.ExecuteScalar().ToString();
            CloseConnection();
            _command.Dispose();
        }
        catch (Exception)
        {
            CloseConnection();
            _command.Dispose();
            throw;
        }
       
        return result;
    }
}    

异常(exception)情况是:

InnerException System.InvalidOperationException: ExecuteReader requires an open and available Connection. The connection's current state is connecting.
at System.Data.SqlClient.SqlConnection.

InnerException System.InvalidOperationException: Invalid operation. The connection is closed.
at System.Data.ProviderBase.DbConnectionClosed.

InnerException System.NullReferenceException: Object reference not set to an instance of an object.

最佳答案


你一起做错了,你应该创建连接但不应该打开它,你应该在需要时打开它并关闭它

我建议也删除这个函数,只使用 using

    public static string CreateConnection()
    {

   string ConnectionString = ConfigurationManager.ConnectionStrings[_connectionString].ConnectionString;
        _connection = new SqlConnection(ConnectionString);
           //remove this line 
        //_connection.Open();
        return "0";
    }

你也不需要这个功能

 public static void CloseConnection()
    {
        _connection.Close();
        _connection.Dispose();
    }

按照建议使用 using 会有帮助


我建议的最佳方法是始终使用 using 和 dispose conenction ,如下所示

using(SqlConnection con = new SqlConnection() )
{
}

如果你担心它会创建太多的对象,那么对于数据库的信息连接池意味着你可以在连接字符串中指定连接池信息,这样你就不必担心在创建连接对象时建立连接.

<add name="sqlConnectionString" connectionString="Data 
Source=mySQLServer;Initial Catalog=myDatabase;Integrated 
Security=True;Connection Timeout=15;Connection Lifetime=0;Min Pool Size=0;Max 
Pool Size=100;Pooling=true;" />

上面是负责池化的连接字符串


示例代码,这是我在 poroject 中的做法,如果您看到代码,我每次都使用 using

处理连接对象
public class DbHelper
{
    #region Private methods

    private static OracleConnection GetConnection()
    {
        string connectionString = DbConnectionString.ConnectionString;
        return new OracleConnection(connectionString);
    }

    private static OracleCommand GetCommand(OracleConnection connection, string commandText, OracleParameter[] param, bool isProcedure)
    {
        OracleCommand dbCommand = new OracleCommand();
        dbCommand.Connection = connection;
        dbCommand.CommandText = commandText;
        if (param != null)
            dbCommand.Parameters.AddRange(param);
        if (isProcedure)
            dbCommand.CommandType = CommandType.StoredProcedure;
        return dbCommand;
    }
    #endregion

    #region public methods
    public static DataTable GetDataTable(string commandText, OracleParameter[] odbcPrams, bool isProcedure = false)
    {
        DataTable dt = new DataTable();
        using (OracleConnection ODBCConn = GetConnection())
        {
            using (OracleCommand dbCommand = GetCommand(ODBCConn, commandText, odbcPrams, isProcedure))
            {
                ODBCConn.Open();
                OracleDataAdapter da = new OracleDataAdapter(dbCommand);
                da.Fill(dt);
            }
        }

        return dt;
    }
    #endregion
}

关于c# - Sql 连接中的连接打开和关闭问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49891443/

相关文章:

c# - 无法加载文件或程序集 'Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

c# - 从输入数据流中查找重复计数...

jquery - 网络应用程序 - 适合智能手机和台式机

c# - 使用 C# 下载 3000 多张图片?

c# - Skype API 连接被拒绝

c# - EntityFramework 将新对象添加到嵌套对象集合

asp.net - asp.net mvc 是怎么算出来的?

java - 使用连接池时,我应该在每次查询时获取连接还是每批获取一次连接?

mysql - 我是否需要在我的 (grails) Web 应用程序中使用 C3P0 池库?

spring - 如何在 Spring WebClient 中管理/创建连接池?