Does SqlConnection get disposed using this function - c#

public CategorieEquipement Select(int NoType)
{
SqlConnection cx = new SqlConnection(WebConfigurationManager.ConnectionStrings["SQLConnect"].Connection String);
SqlDataReader reader;
CategorieEquipement lstCategorie = new CategorieEquipement();
try
{
cx.Open();
SqlCommand com = new SqlCommand("SELECT_CategorieEquip", cx);
com.CommandType = System.Data.CommandType.StoredProcedure;
com.Parameters.AddWithValue("#where",NoType);
reader = com.ExecuteReader();
while (reader.Read())
{
lstCategorie.CodeRef = reader["CodeRef"].ToString();
}
}
catch (Exception ex)
{
Debug.WriteLine("SELECT ERROR : " + ex.ToString());
return null;
}
finally
{
if (cx != null)
{
cx.Close();
}
}
return lstCategorie;
}
}
My question is if I remove the finally block of code, will the garbage collector close the connection when disposing of the SQlConnection object?
I know it is a better practice to be explicit but my coworker doesn't agree .

will the garbage collector close the connection when disposing of the
SQlConnection object?
Garbage collector is not responsible for calling Dispose on an object, usually Dispose is called in the Finalizer, only then GC would be able to properly dispose the object.
One important thing to note is that you cannot predict when the garbage collection process will run, so it is always better to explicitly dispose objects (which implements IDisposable).
As far as database connections are concerned the approach should be open as late as possible and close as early as possible.
In the case above cx.Close(); should be enough, instead, you can also call cx.Dispose, But a better approach would be to enclose the SqlConnection in using statement block.
That will translate into try/finally block and it will ensure the SqlConnection disposal.

The garbage collection will dispose it, but since it is non-deterministic you don't know when it will do it.
C# provide the using structure to dispose unmanaged code and it is recommended to use it:
using (SqlConnection cx = new SqlConnection(WebConfigurationManager.ConnectionStrings["SQLConnect"].ConnectionString);)
{
}
Tell your co-workers they ought to wrap any instance of objects that implement the IDisposable interface in a using so that they will be disposed in a deterministic fashion to ensure a correct management of the application resources and avoid problems like memory leaks.

Related

Is disposing the SqlTransaction required? [duplicate]

Do I need to call dispose in the finally block for SqlTransaction? Pretend the developer didnt use USING anywhere, and just try/catch.
SqlTransaction sqlTrans = con.BeginTransaction();
try
{
//Do Work
sqlTrans.Commit()
}
catch (Exception ex)
{
sqlTrans.Rollback();
}
finally
{
sqlTrans.Dispose();
con.Dispose();
}
Do I need to use try-finally or the using-statement to dispose the SqlTransaction?
It does not hurt to have it. This is true for every class implementing IDisposable, otherwise it would not implement this interface.
But normally the garbage collector deals with unreferenced objects(it doesn't mean that the GC calls dispose, which isn't true), so you need it only for unmanaged resources. But because i also don't want to call dispose on every other variable or use the using-statement everywhere, it it's always worth to look into the actual implementation of the class' Dispose method.
SqlTransaction.Dispose:
protected override void Dispose(bool disposing)
{
if (disposing)
{
SNIHandle target = null;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
target = SqlInternalConnection.GetBestEffortCleanupTarget(this._connection);
if (!this.IsZombied && !this.IsYukonPartialZombie)
{
this._internalTransaction.Dispose();
}
}
catch (OutOfMemoryException e)
{
this._connection.Abort(e);
throw;
}
catch (StackOverflowException e2)
{
this._connection.Abort(e2);
throw;
}
catch (ThreadAbortException e3)
{
this._connection.Abort(e3);
SqlInternalConnection.BestEffortCleanup(target);
throw;
}
}
base.Dispose(disposing);
}
Without understanding all(or anything) what is happening here i can say that this is more than a simple base.Dispose(disposing). So it might be a good idea to ensure that a SqlTransaction gets disposed.
But because SqlConnection.BeginTransaction creates the transaction it could also be a good idea to reflect this also:
public SqlTransaction BeginTransaction(IsolationLevel iso, string transactionName)
{
SqlStatistics statistics = null;
string a = ADP.IsEmpty(transactionName) ? "None" : transactionName;
IntPtr intPtr;
Bid.ScopeEnter(out intPtr, "<sc.SqlConnection.BeginTransaction|API> %d#, iso=%d{ds.IsolationLevel}, transactionName='%ls'\n", this.ObjectID, (int)iso, a);
SqlTransaction result;
try
{
statistics = SqlStatistics.StartTimer(this.Statistics);
SqlTransaction sqlTransaction = this.GetOpenConnection().BeginSqlTransaction(iso, transactionName);
GC.KeepAlive(this);
result = sqlTransaction;
}
finally
{
Bid.ScopeLeave(ref intPtr);
SqlStatistics.StopTimer(statistics);
}
return result;
}
As you can see. The GC will also keep the Connection alive when a Transaction is created. It also doesn't hold a reference to the transaction since it only returns it. Hence it might not be disposed even when the connection is already disposed. Another argument to dispose the transaction.
You might also have a look at the TransactionScope class which is more fail-safe than BeginTransaction. Have a look at this question for more informations.
In the general case, every IDisposable object you construct or obtain, and own, you have to dispose of.
In the specific case, there are some exceptions, but SqlTransaction is not one of them.
As per the the documentation of SqlTransaction.Dispose:
Releases the unmanaged resources used by the DbTransaction and optionally releases the managed resources.
(my emphasis)
Since the documentation does not state that those unmanaged resources are released when you issue a commit or a rollback, you will need to dispose of this object.
I think you can just close connection. I checked the code of BCL -- seems like connections takes care of its transaction -- no need to close it explicitly.

c# if catch exception of a new method, will GC collects this object?

private void BeginListen()
{
while (isWatch)
{
try
{
Socket newSocket = socket.Accept();
ConnectionClient conn = new ConnectionClient(newSocket, ShowMsg, RemoveClientConnection, SendMsgToController);
string strRemoteEndPoint = newSocket.RemoteEndPoint.ToString();
if (dictConn.ContainsKey(strRemoteEndPoint.Substring(0, strRemoteEndPoint.LastIndexOf(":"))))
dictConn[strRemoteEndPoint.Substring(0, strRemoteEndPoint.LastIndexOf(":"))].isRec = true;
else
dictConn.Add(strRemoteEndPoint.Substring(0, strRemoteEndPoint.LastIndexOf(":")), conn);
UpdateControllerStatus(strRemoteEndPoint, " online");
}
catch (Exception ex)
{
ExceptionLog(ex);
}
}
}
This method is used for listening.
If I use thread to create this method
myThread = new Thread(new ThreadStart(BeginListen));
myThread.IsBackground = true;
myThread.Start();
Will it be collected by GC when catching an exception?
Or do I need to add GC.Collect(); manually in the catch?
What do you want to be collected? Well, generally you shouldn't call GC.Collect yourself.
I would leave it for the GC to collect the objects and reclaim memory resources. But when something implements IDisposable, you generally should use the using statement.
In the example provided, maybe you don't need to use a using statement, because the socket may be used later, also, maybe there is already some code to dispose the object inside your ConnectionClient class. Disposing it now could cause you problems.
But generally you can use the using statement to automatically handle the disposal of resources, eg opening file streams, creating memory streams, and so on.
To learn more about what the using statement does, Click here.

using SqlConnection.Open inside using () {} block?

Do I need to use SqlConnection.Open() inside:
using (SqlConnection var = new SqlConnection())
{
//my operations
}
?
What happens if I don't dispose this connection by SqlConnection.Close() function?
Yes, you need to Open your connection inside the using block.
If you don't explicitly Close() the connection, the end of the using block will do it for you as the using disposes of the connection. When a connection is disposed it is automatically closed.
The using statement is just syntactic sugar which ensures that Dispose gets called on the IDisposable instance no matter what, so in your case using (SqlConnection connection = new SqlConnection()) is roughly equivalent to (as per MSDN):
SqlConnection connection = new SqlConnection();
try
{
// Operations.
}
finally
{
if (connection != null)
{
connection.Dispose();
}
}
In the case of SqlConnection Dispose and Close calls are actually equivalent, so a call to Close would be redundant within a using (SqlConnection) block.
Calling Open, on the other hand, will still be necessary in many scenarios (before a call to ExecuteReader, ExecuteScalar, ExecuteNonQuery, for example). The using statement has no effect on whether or not you need to explicitly open the connection - only on whether or not you need to explicitly close it.
Provides a convenient syntax that ensures the correct use of
IDisposable objects
using Implements IDisposable Internally
using(SqlConnection con=new SqlConnection("myCOnstr"))
{
con.open();
using(SqlCommand con=new SqlCommand("myCmd",con))
{
//......Insert/Update /Delete
}
}

disposing multiple objects that reference each other in c#

Okay, I've searched "similar" topics but still haven't come across any answer to what I'm going to ask here.
I have a function that creates multiple sql objects under the System.Data.SqlClient namespace. I've read that the using statement disposes of an object after the using block but the variables declared are readonly. My function reuses some of these variables, so I can't really declare them within a using statement.
Here is the body of my function for clarity. Should I call Dispose on the other objects (command, transaction, reader, etc) or will using recursively dispose of them through the connection object? How should I dispose these objects?
I'm still new to C# (I come from C/C++ background) so please forgive me if the question sounds very ignorant.
public string SignIn(string userId, string password)
{
SqlCommand sqlCommand = null;
SqlTransaction sqlTransaction = null;
string sessionId = "";
using(SqlConnection sqlConnection = new SqlConnection Properties.Settings.Default.SessionManagerDBConnectionString))
{
try
{
sqlConnection.Open();
sqlCommand = sqlConnection.CreateCommand();
sqlCommand.CommandText = "GetUserByUserIdPassword";
sqlCommand.CommandTimeout = 30;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
sqlTransaction = sqlConnection.BeginTransaction("SampleTransaction");
// more database activity, execute command, store results in datareader
sqlTransaction.Commit();
sqlConnection.Close();
}
catch (SqlException ex)
{
if(sqlTransaction != null)
sqlTransaction.Rollback();
MessageBox.Show(ex.Number + ":" + ex.Message, ex.Server + ":" + ex.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
return sessionId;
}
I tried to search for similar questions again and found some closer answers.
Is SqlCommand.Dispose() required if associated SqlConnection will be disposed?
Does SqlCommand.Dispose close the connection?
I suppose I should add a finally clause to my try-catch and call several Dispose methods there for all the sql objects I've created. I hope that suffices or is there a recommended style of doing this?
finally
{
if(sqlCommand != null)
sqlCommand.Dispose();
if(sqlTransaction != null)
sqlTransaction.Dispose();
...
}
I tried putting a using statement within the try-catch block for one of the sqlCommand objects, but if that part of the code aborts when an exception is thrown, the execution jumps down to the catch portion. The using does not dispose that sqlCommand object.
try
{
...
using(sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = "GetUserByUserIdPassword2";
sqlCommand.CommandTimeout = 30;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
SqlDataReader reader = sqlCommand.ExecuteReader(CommandBehavior.SingleRow);
// throws exception, no stored procedure "GetUserByUserIdPassword2"
}
...
}
catch() {}
// sqlCommand still accessible at this point because using above was "aborted".
If the object implements IDisposable, then use using. If you need to create a new SqlCommand for some reason then finish one using block and start a new one. Or nest them if you still need access to the first SqlCommand.
You can reuse SqlCommand objects, as long as you haven't got a datareader still open from the command. So, you could create a SqlCommand, set all its properties and execute it, then reset all its properties and execute it again and so on. This does save slightly on the costs of memory allocation, but I think it also reduces the clarity of the code, so it is something I would only do if profiling proved it necessary.
will using recursively dispose of them through the connection object
Of course, using knows nothing about SqlConnections or other ADO.NET objects. All it knows is to call Dispose. Whatever the object being disposed does is what happens.
It happens to be the case that disposing a SqlConnection also disposes of the resources of all readers and commands associated with the connection. You only need to dispose the connection.
I don't know whether this is documented on MSDN but I know it from decompiling the assemblies. For compatibility reasons they can never change this behavior so it is safe to rely on it.
In general, you must call dispose on any object implementing IDisposable. Exception to this rule is when you know for sure that it is safe to not call Dispose. Like in this case.
I think I found the answer!
Even though the sqlCommand object was still accessible in the bottom parts of the code when a nested using statement was skipped by a thrown exception, sqlCommand is still disposed later on. I tested this by actually assigning a function to the disposed event of said sqlCommand object.
The code here is slightly different than above because of the transaction object requirement. But the logic is essentially the same.
try
{
using(sqlCommand = new SqlCommand("GetUserByUserIdPassword2", sqlConnection, sqlTransaction))
{
sqlCommand.CommandTimeout = 15;
sqlCommand.CommandType = CommandType.StoredProcedure;
SqlParameter parameterUserId = sqlCommand.Parameters.Add("#UserId", SqlDbType.NVarChar, 32);
parameterUserId.Value = userId;
SqlParameter parameterPassword = sqlCommand.Parameters.Add("#Password", SqlDbType.NChar, 64);
parameterPassword.Value = this.GetSHA256Hash(password);
sqlCommand.Disposed += new System.EventHandler(this.sqlCommand_Disposed);
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.SingleRow);
// exception thrown, no sored proc "GetUserByUserIdPassword2"
sqlDataReader.Close();
}
}
catch(...) {}
...
private void sqlCommand_Disposed(object sender, EventArgs e)
{
MessageBox.Show("sqlCommand has been disposed");
}
So, basically, even if a nested using statement is "aborted" by a thrown exception within the try block, and execution is skipped down to the catch block, the Dispose method is still called for that object after the function exits (or when the variable goes out of scope).
I presume this behavior is the same for any number of nested using statements.
in CSharp, using is a special keyword which have different acts in code..
if you put using to top of the codepage then using acts as c++ ' s Include or VB (and some other script langs') Import
if you write a "using" which follows by a paranthesis then it acts like an alias of Dispose() method of CSharp.. or Destructor tilda of c++ or free() method of plain c..
About SQL Connection.. Best way is first Close() the connection (so with this, connection is still alive -actually just ready to use- but null.. return to wait new order in connection pool.. ) and then dispose if you need..
if you have still problems and suspected that calling the Dispose() method not enough to free the resources
then you can use Garbage Collector's Collect() static method to force the garbage collection
But not so much recommended by Microsoft because of face with accidental garbage collection problems (i.e. you collect the form but need some variable from that form )
in example of usage :
public void Dispose (bool ForceToCollect )
{
if (ForceToCollect)
GC.Collect (0, GCCollectionMode.Forced );
}
In Gc.Collect() method you can set which group of data memory freed with first option where is int..if you plan to free resources of the last group - means last created group of items, as an example last created form instance and its all child controls - then int should be 0; the one which is 1 before the last created then should be 1 and so on..
Hope this helps..

When using "DbConnection" should I use "using" or try-catch-finally to use DbConnection.close() to close the connection?

I was searching the web for a while now. But didn't find any clear answer to my question. Whether when connecting to a database I should use "using" or I can just go with try-catch-finally? What I mean is:
I don't know if I should call the dispose method each time I finish interacting with the database or just close the connection.
static public List<Category> GetAll()
{
List<Category> CategoryList;
try
{
BaseDAO.Dbconn.Open();
BaseDAO.SetCommand(BaseDAO.CommandAction.Read, "SELECT * FROM Categories");
CategoryList = new List<Category>();
using (DbDataReader reader = BaseDAO.Dbcmd.ExecuteReader())
{
while (reader.Read())
{
int ID = reader.GetInt32(reader.GetOrdinal("CategoryID"));
string Name = reader.GetString(reader.GetOrdinal("CategoryName"));
string Description = reader.GetString(reader.GetOrdinal("Description"));
CategoryList.Add(new Category(ID, Name, Description));
}
}
return CategoryList;
}
catch (Exception ex)
{
BaseDAO.Dbconn.Dispose();
throw ex;
}
finally { BaseDAO.Dbconn.Close(); }
}
The "Dbconnection" is static not sure if this is a good solution as well...
I am getting to know ADO and just wanted to know what's the best answer for this kind of question.
It doesn't make any difference - whatever you prefer. The using clause gets turned into a try-finally by the compiler anyway.
EDIT I just noticed you are only calling Dispose if an exception occurs. You should move this into the finally clause as well. Dispose will call Close, so you don't need to specifically call it if you don't want to.
Further edit Given that, as you say, your DbConnection is static, then you don't want to call Dispose, but you do need to call Close. However, there should not be any need to use a static DbConnection - connection pooling will take care of efficiently handling the connections. Your code should create a new connection instance every time.
Reference: Using Statement C#.
The using statement allows the programmer to specify when objects that use resources should release them.
The object provided to the using statement must implement the
IDisposable interface. This interface provides the Dispose method,
which should release the object's resources.
A using statement can be exited either when the end of the using statement is reached or if an exception is thrown and control leaves the statement block before the end of the statement.
Reference : Example
As per Code Project, the .NET CLR converts
using (MyResource myRes = new MyResource())
{
myRes.DoSomething();
}
to:
{
// limits scope of myRes
MyResource myRes= new MyResource();
try
{
myRes.DoSomething();
}
finally
{
// Check for a null resource.
if (myRes!= null)
// Call the object's Dispose method.
((IDisposable)myRes).Dispose();
}
}
Calling Dispose is equivalent to calling Close in most (if not all) DbConnection implementations, so there's no need to call the former if you are already calling the latter. Just make sure you do so in a finally in case there's an exception.

Categories