找到许多解决方案,但没有一个解决方案适合我的场景。
问题: 我正在开发在 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/