Further to my recent questions, I've now closed most of the connections that our web application was leaving open. However, the connection created by the function below remains open. Can anyone identify why it is not closing?
public DataTable GetSubDepartment(int deptId)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(Defaults.ConnStr))
{
SqlCommand cmd = new SqlCommand("proc_getDepartmentChild", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#dptParent", deptId));
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
}
return dt;
}
* EDIT *
Following #HenkHolterman's comment:
I'm using SQL Server Management Studio Activity log to view the open connections. This one is listed as sleeping. SO what you say makes sense. Is there any way I can tell that this is a pooled connection rather than an open one?
Most probably because it went back to the connection pool.
Call
SqlConnection.ClearAllPools();
to clear the pool, then it should disappear. This could sometimes be useful, but is usually not needed.
I would assume that it's hanging in the connectionpool
Related
I want to search data from another SQL Server table (Stocks_Item) to this form (IC) dataGridView1, I can view that data (from Stocks_Item) in this dataGridView1 but I couldn't search. Please help me.
Here is my code:
private void button5_Click(object sender, EventArgs e)
{
conn.Close();
try
{
conn.Open();
SqlCommand selectCommand = new SqlCommand("Select * from Stocks_Item where Stock_No = #Stocks_no", conn);
selectCommand.Parameters.Add(new SqlParameter("Stocks_no", txtsearch_stock_no.Text.ToString()));
SqlDataReader reader = selectCommand.ExecuteReader();
bool rowFound = reader.HasRows;
SqlDataAdapter data = new SqlDataAdapter("Select * from Stocks_Item", conn);
DataTable dt = new DataTable();
data.Fill(dt);
dataGridView1.DataSource = dt;
/* SqlDataAdapter sda;
DataTable dt1;
sda = new SqlDataAdapter("select * FROM colombo_branch ",conn);
dt1 = new DataTable();
sda.Fill(dt1);
dataGridView.DataSource = dt1;*/
MessageBox.Show("Search Found", "Form", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
conn.Close();
}
There are many flaws in your code, but the one that is specifically causing your error is because you are not properly closing the SqlDataReader here:
SqlDataReader reader = selectCommand.ExecuteReader();
bool rowFound = reader.HasRows;
As a result, the following line, which also attempts to open a data reader internally throws the exception:
data.Fill(dt);
Normally, you want to use a SqlDataReader inside a using block, something like:
bool rowFound;
using(SqlDataReader reader = selectCommand.ExecuteReader())
{
rowFound = reader.HasRows;
}
... to ensure proper and timely disposal. But in this case, I fail to see the point of that block of code anyways. So why not just remove it altogether?
Additional comments:
Avoid global connections. The fact that the method begins by closing the connection is not a good sign.
Always use using blocks around your SqlConnection, SqlCommand, SqlDataReader, SqlDataAdapter, etc... instances to make sure you don't run into these types of errors or leak resources.
I believe that SqlDataAdapter opens/closes a connection for you. Since you're doing that earlier in your code and using a reader against it, that would be the cause. You could use either the reader or the adapter, but typically wouldn't want to mix them in one connection without properly closing/disposing.
FYI, the MSDN SqlDataAdapter code example utilizes this auto open/close behavior of SqlDataAdapter
I'm using System.Data.SQLite (v1.0.104) in a multi-threaded C# application. When a thread want's to update the DB, it opens a new connection in a using statement (calling the method below) and executes its queries. This seems to work well with the connection string in the following example:
[MethodImpl(MethodImplOptions.Synchronized)]
private SQLiteConnection CreateSQLiteConnection()
{
var connection = new SQLiteConnection("Data Source=myDatabase.sqlite;Version=3");
connection.Open();
return connection;
}
However if I add Pooling=True to the connection string, I can observe the following: One thread is blocking on connection.Open(); indefinitely while the other threads are waiting to enter CreateSQLiteConnection. As far as I can tell from the debugger, at this point in time no thread is actually performing any kind of update to the db.
I already tried setting busy and default timeouts but that didn't change anything. I also know that the sqlite documentation suggests to avoid multiple threads altogether but that is currently not an option.
I've added the Synchronized attribute to avoid potential issues regarding multiple threads simultaneously calling SQLiteConnection.Open but it did not seem to make a difference.
Does anyone know what might cause SQLiteConnection.Open to behave like that or what I could try to get more details about this?
You can use SQLite Version 3 ==> .s3db,
public SQLiteConnection dbConnection = new SQLiteConnection(#"Data Source=E:\Foldername\myDatabase.s3db;");
SQLiteConnection cnn = new SQLiteConnection(dbConnection);
cnn.Open();
string sql = "SELECT * FROM Tble_UserSetUp";
DataSet ds = new DataSet();
SQLiteCommand mycommand = new SQLiteCommand(cnn);
mycommand.CommandText = sql;
SQLiteDataAdapter da = new SQLiteDataAdapter();
da.SelectCommand = mycommand;
da.Fill(ds);
cnn.Close();
I use the code below to get data from mySql in C#. When I do that I get the error mentioned below the code. I found some question about the subject but they used DataReader, and I'm not.
MySqlConnection sq = new MySqlConnection("...");
sq.Open();
MySqlCommand sc = new MySqlCommand("select * from users", sq);
DataSet ds = new DataSet();
MySqlDataAdapter da = new MySqlDataAdapter(sc);
da.Fill(ds);
sq.Close();
My Error:
There is already an open DataReader associated with this Connection
which must be closed first.
in your connection string just add "MultipleActiveResultSets=True;"
I don't know if this fixes your issue, however...
Use the using statament for your connection, the command and the dataadapter. This disposes all objects that implement IDisposable and also closes the connection:
using(var sq = new MySqlConnection("..."))
using(var sc = new MySqlCommand("select * from users", sq))
using(var da = new MySqlDataAdapter(sc))
{
DataSet ds = new DataSet();
da.Fill(ds);
// you don't need to open/close the connection with a datadapter
} // but even without a dataadapter the using would have been closed the connection here
as the error said, you aren't closing every connection you open.
Probably because of and exception you get. you can use Tim's suggest:
using(var sq = new MySqlConnection("..."))
using(var sc = new MySqlCommand("select * from users", sq))
using(var da = new MySqlDataAdapter(sc))
or you can use try catch statement:
try
{
// Your code here
}
catch
{
// Whatever code you want here
}
finally
{
da.Close();
sc.Close();
sq.Close();
}
new MySqlCommand("select * from users", sq)
This implementation of the MySqlDataAdapter opens and closes a
MySqlConnection if it is not already open. This can be useful in a an
application that must call the DbDataAdapter.Fill method for two or
more MySqlDataAdapter objects. If the MySqlConnection is already open,
you must explicitly call MySqlConnection.Close or
MySqlConnection.Dispose to close it.
so, no need to open the connection, MySqlDataAdapter will open it when needed.
better to use using statements as other answers.
Question:
Why is the following code leaking connections ?
public System.Data.DataTable GetDataTable()
{
System.Data.DataTable dt = new System.Data.DataTable();
string strConnectionString = "Data Source=localhost;Initial Catalog=MyDb;User Id=SomeOne;Password=TopSecret;Persist Security Info=False;MultipleActiveResultSets=False;Packet Size=4096;";
System.Data.SqlClient.SqlConnectionStringBuilder csb = new System.Data.SqlClient.SqlConnectionStringBuilder(strConnectionString);
csb.IntegratedSecurity = true;
string strSQL = "SELECT * FROM T_Benutzergruppen";
using (System.Data.SqlClient.SqlConnection sqlcon = new System.Data.SqlClient.SqlConnection(csb.ConnectionString))
{
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(strSQL, sqlcon))
{
if (sqlcon.State != System.Data.ConnectionState.Open)
{
sqlcon.Open();
}
// First attempt
//System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", sqlcon);
//sqlda.Fill(dt);
cmd.ExecuteNonQuery();
}
if(sqlcon.State != System.Data.ConnectionState.Closed)
sqlcon.Close();
}
//sqlcon.ConnectionString = csb.ConnectionString;
// Second attempt
//System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
//sqlda.Fill(dt);
return dt;
}
If I go into SQL-Server activity monitor, I see Session 68
SELECT * FROM T_Benutzergruppen
Additional question:
If question:
If I comment out everything except the ConnectionStringBuilder, and only execute the below code in this function, why does it leak a connection, too ?
// Second attempt
System.Data.SqlClient.SqlDataAdapter sqlda = new System.Data.SqlClient.SqlDataAdapter("SELECT * FROM T_Benutzer", csb.ConnectionString);
sqlda.Fill(dt);
Note:
The executenonquery makes no sense, it's just there for testing purposes.
If I let it run in the debugger, I see that
sqlcon.Close();
get's executed, so the problem is not the
if(sqlcon.State != System.Data.ConnectionState.Closed)
Connection Pooling. Don't worry about it.
This is normal behavior.
http://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.100).aspx
ADO.Net pools connections so that they can be re-used because they are relatively expensive to create.
Connecting to a database server typically consists of several time-consuming steps. A physical channel such as a socket or a named pipe must be established, the initial handshake with the server must occur, the connection string information must be parsed, the connection must be authenticated by the server, checks must be run for enlisting in the current transaction, and so on.
In practice, most applications use only one or a few different configurations for connections. This means that during application execution, many identical connections will be repeatedly opened and closed. To minimize the cost of opening connections, ADO.NET uses an optimization technique called connection pooling.
http://msdn.microsoft.com/en-us/library/8xx3tyca(v=vs.100).aspx
Also, there is no need to explicitly call .Close(). Your using block will call IDisposable.Dispose(), which will close the connection properly.
Does SqlDataAdapter close the SqlConnection after the Fill() function or do I need close it myself?
string cnStr = #"Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
cn = new SqlConnection(cnStr);
SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn);
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
cn.Close() // ????????
Console.WriteLine(ds.Tables[0].Rows.Count);
Console.WriteLine(cn.State);
In your current usage, it will close for you:
If the IDbConnection
is closed before Fill is called, it is opened to retrieve data and
then closed. If the connection is open before Fill is called, it
remains open.
http://msdn.microsoft.com/en-us/library/zxkb3c3d.aspx
I think it's always better to explicitly cater for it yourself with a using statement:
using (SqlConnection conn = new SqlConnection(""))
{
conn.Open();
// Do Stuff.
} // Closes here on dispose.
This is often more readable and doesn't rely on people understanding the inner workings of SqlDataAdapter.Fill, just the using statement and connections.
However, if you know the connection is closed before the adapter uses it (as in, you've just created the connection) and it's not used for anything else, your code is perfectly safe and valid.
Personally, I'd write something like this:
string cnStr = "Data Source=TEST;Initial Catalog=Suite;Persist Security Info=True;User ID=app;Password=Immmmmm";
DataSet ds = new DataSet();
using (SqlConnection cn = new SqlConnection(cnStr))
using (SqlCommand cmd = new SqlCommand("SELECT TOP 10 * FROM Date", cn))
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
conn.Open();
adapter.Fill(ds);
}
As I know you need to close the connection by you own
Best way to do is
using(SqlConnection con = new SqlConnection())
{
// you code
}
this will close you connection automatically
using block in C# comes very handly while dealing with disposable objects. Disposable objects are those objects that can explicitly release the resources they use when called to dispose. As we know .Net garbage collection is non-deterministic so you can’t predict when exactly the object will be garbage collected.
Read this post for more in details : understanding ‘using’ block in C#