I have and asp.net mvc 3 web site. When running it on local VS web server or IIS express it`s ok. But when running it on IIS (IIS 7.5 Windows 2008 R2) it seems like memory leak as memory usage is growing all the time. Any ideas?
One more update: there`s such a code in the app:
SqlConnection conn = new SqlConnection { //creating connection here };
conn.Open();
SqlCommand command = conn.CreateCommand();
try
{
var reader = command.ExecuteReader();
while (reader.Read())
{
//read the data
}
}
finally
{
conn.Close();
}
Maybe there should be something like reader.Dispose? Can it be the cause of memory leak?
UPDATE: for some reason gc.Collect fixes the issue. But it`s not hte way out as calling gc.collect all the way is a bad idea.
well best practice here would be to use brackets, this is a great feature of c#. when you use the "using" keyword with a bracket, it would dispose the used object automatically, when running out of the bracket scope. here's an example;
// SqlConnection implements IDisposable, will be disposed after bracket is closed
using(SqlConnection conn = new SqlConnection())
{
conn.Open();
// SqlCommand implements IDisposable, will be disposed after bracket is closed
using(SqlCommand command = conn.CreateCommand())
{
// DataReader implements IDisposable, will be disposed after bracket is closed
using(var reader = command.ExecuteReader())
{
while (reader.Read())
{
// read here.
}
}
}
}
Here's also the microsoft link that says "The connection is automatically closed at the end of the using block." http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.close%28v=VS.85%29.aspx
I hope it helps.
Related
I am doing windows forms application with connection to SQL Server (disconnected mode). Every action I handle in my application needs the connection. So I don't know where to close the connection.
I am asking what if i don't close the connection. I know that there is no runtime error that appears. But is there any other error that could appear?
There is a risk that if you are using the same connection for each method, from a private field or GetConnection() method etc.; you could end up trying to read/write when the connection is still open.
This could then throw errors and you could end up in a whole heap of it, if using a live SQL database.
If you can, create a new instance of a connection in a using statement each time you want to access the DB.
Like this:
var connectionString = "YourConnectionStringToTheDB";
var queryString ="YourSQLQueryHere"; // FROM * IN tbl SELECT * etc...
using (SqlConnection connection = new SqlConnection(
connectionString))
{
using (SqlCommand command = new SqlCommand(queryString, connection))
{
command.Connection.Open();
command.ExecuteNonQuery();
}
}
This way it is closed and disposed of when the code runs outside of the using statement's scope.
Notice that the SqlCommand is also in a using statement, as it too can be disposed of.
This is cleaner code and marks the objects for disposal by the Garbage Collector. (Google is your friend) - BIG topic; a lot of stuff to read.
Here is a similar question which gives you some more detail: The C# using statement, SQL, and SqlConnection
EDIT
Better still, you could wrap your SQL code in a try { } catch { } block to handle any errors at runtime.
I was using this code:
public class SQLConnection : IConnection
{
private SqlConnection _sqlConnection = null;
//bunch of interface implementations for my project
//the destructor
~SQLConnection()
{
if(_sqlConnection != null)
{
if(_sqlConnection.State == ConnectionState.Open)
{
_sqlConnection.Close();
}
_sqlConnection.Dispose();
}
}
}
This was working well until some time ago, when I started receiving this error: Internal .Net Framework Data Provider error 1
After googling a bit, I found this link (the Caution part) and I think that's what's happening to me.
My class was managing the connection state opening and closing each time, but now that it seems I can't manage it this way, is there any other way that I can do this without having to go to every function that I use the connection and call connection.Close() explicitly?
Always use 'using' for safely disposing the connections.
using(var _sqlConnection = new SqlConnection())
{
//code here
_sqlConnection.Open();
}
//Safely disposed.
Also, it is never a good idea to use destructor explicitly in C# code unless you have unmanaged code.
You're probably receiving this error when one code is trying to access SQLConnection that has been already garbage collected. This usually will happen in cases like this one
SqlConnection sqlConn;
using (var sqlConnection = new SqlConnection())
{
sqlConn = sqlConnection;
sqlConnection.Open();
}
sqlConn.Close();
I know this example looks silly as it's overly simplified, but it happens often when programmers tend to share a connection object between Managing Classes. Look for any recent changes in your code. Maybe you're passing an instance of a connection between multiple objects. One of those objects gets Garbage Collected and in turn the connection gets disposed too.
I'm having some trouble. I have a SqlCommand in a using block. Usually this works fine. This time however, the code exits the using block but the command does not get disposed. It has me stumped.
using (SqlCommand transferCommand = new SqlCommand(strHeaderStoredProcedure, connection))
{
transferCommand.CommandType = System.Data.CommandType.StoredProcedure;
transferCommand.Parameters.Add("#InvtTransferID", SqlDbType.UniqueIdentifier).Value = InvtTransferID;
SqlDataReader transferReader = transferCommand.ExecuteReader();
while (transferReader.Read())
{
//do my stuff, this all works fine
}
}
using (SqlCommand transferCommand = new SqlCommand(strDetailsStoredProcedure, connection))
{
transferCommand.CommandType = System.Data.CommandType.StoredProcedure;
transferCommand.Parameters.Add("#InvtTransferID", SqlDbType.UniqueIdentifier).Value = InvtTransferID;
SqlDataReader transferReader = transferCommand.ExecuteReader(); <-- Error happens here.
}
I'm trying to reuse my connection to run a bunch of stored procedures. It is the strangest thing. I have some code on another form that is virtually identical and it runs fine, disposing the command and allowing me to make another. Any ideas what I'm doing wrong? (I'm trying to make this code look nice in the post but it seems to be beyond my meager power...so sorry for the messy code.)
Error is: There is already an open DataReader associated with this Command which must be closed first.
What you have is an open SqlDataReader (transferReader), Close and Dispose the datareader or use a using() for it.
I assume the command is not being released because the reader is still open.
As a bit of extra info, here is what the compiler does behind the scenes when you write an using statement.
using(IDisposable x)
{
//some work here
}
Turns into
IDisposable x = //some IDisposable
try
{
//do work here
}
finally
{
x.Dispose()
}
As Gusman mentioned , using cannot guarantee the object destruction, it just calls the object's dispose method. It's the IDisposable's reponsability to clean up any used resources
I hope this helps
I am working on a project which, up until today, has been fine. However now when I run it and it goes through a few different Stored Procedure calls it is throwing an InvalidOperationException with the message The connection was not closed. The connection's current state is open.
I get that I could put in a check to see if the connection is already open, but this code hasn't changed (it is under Version Control and isn't modified) so I'm looking for other potential explanations.
Could there be some lock in SQL which isn't being released? Is there a process which I should look out for and kill?
I can't really post the code as there is a lot of it, and it is split up into smaller methods which makes it harder to pull out individual items. E.g:
public SqlConnection Connection
{
get
{
this._connection.Open();
return _connection;
}
}
public IDataReader RetrieveRecord(int Id)
{
//SP
SqlCommand cmd = this.Connection.CreateCommand();
cmd.CommandText = "SelectRecord";
cmd.CommandType = CommandType.StoredProcedure;
//Parameters
cmd.Parameters.Add(new SqlParameter("#tID", Id));
//instruct the data reader to close its connection when its Close method is called by passing the CommandBehavior.CloseConnection
return cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
Nothing massively complex, I just don't understand why this connection is now throwing an exception.
The DAL is not stable enough:
You open a Connection that is not closed if something goes wrong in RetrieveRecord.
You should create a new connection inside RetrieveRecord and close it there in a finally block.
Opening a connection is cheap thanks to Connection Pooling.
Problem is with the line
this._connection.Open();
Because you are trying to open an already opened connection.
Try this to check before opening a connection:
if (this._connection.State == ConnectionState.Closed)
this._connection.Open();
Sorted. Two reboots cleared whatever was keeping the connection open.
When you are talking about killing process, I think you know c# well.
You should always use
using()
{
}
Like:
using(SqlConnection con=new SqlConnection("connectionString"))
{
// Do something with con
using(SqlCommand cmd=new SqlCommand("cmdText",con))
{
// Do something with cmd
}
}
You know that SqlCommand and SqlConnection implement IDisposable
So when you put those objects within using, the connection closing and clean up job is automatically done.
No need to close the connection manually in the code, since using will do the work for you.
I'm refactoring some old code as we're periodically having connection pool issues on a clients site.
While some code has wrapped DB connections in try/catch blocks I'll be using the using(){} thing (is there a proper term for this?)
So I'd like some clarification on how to use it in our situation to make as few changes as possible.
What we currently have is (mostly) something like this:
SqlConnection sqlConn = new SqlConnection();
SqlCommand sqlCmd = new SqlCommand();
try
{
// DB stuff here
}
finally
{
sqlCmd.Dispose();
sqlConn.Dispose();
}
Some connections aren't wrapped up at all.
So, I'm thinking of changing it to this:
using (SqlConnection ThisConnection = new SqlConnection(ConnectionString))
{
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = ThisConnection;
// DB stuff here
}
}
I've tried this and it works. But I know there's a difference between something working and something working well :)
So, a few questions:
If the SqlConnection is assigned to SqlCommand.Connection and I only wrap up the SqlCommand in a using, will the connection be closed and disposed then the SqlCommand is?
If not, is the above code ok? Or should the SqlCommand using be before the SqlConnection or does it not matter?
When the object is disposed at the end of the using is this absolutely guaranteed to close the DB connection?
All feedback greatly appreciated, cheers.
The using approach is preferable; much harder to get it wrong and leave scenarios where objects can escape without being disposed. Unless you have a very specific reason, it should be your default. You can reduce the nesting, though:
using (SqlConnection ThisConnection = new SqlConnection(ConnectionString))
using (SqlCommand sqlCmd = new SqlCommand())
{
sqlCmd.Connection = ThisConnection;
// DB stuff here
}
When the object is disposed at the end of the using is this absolutely guaranteed to close the DB connection?
It will dispose it; the underlying connection (via any of these approaches) will usually still be pooled, though.
Of course, I also submit that the easiest way to do this is to use less code - less to get wrong. For example, I'd be very tempted to use "dapper", which avoids the need to mess with the commands, readers, parameter collections, etc:
int id = 123;
string name = "abc";
using (var conn = new SqlConnection(ConnectionString))
{
conn.Execute("Some TSQL", new { id, name });
}
if you dispose your connection, you need dispose your command, calling Dispose on it will supress the call to the finalizer. Add using command after using conenction
Don't set your command before connection
Yes, because you close your not managed object , who is coonnection
Remark : using bloc is preferred that try catch finally for basic need without custom treatment in catch bloc
msdn sample link : http://msdn.microsoft.com/fr-fr/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx
this article don't treat using command but speak about connection