Using the using statement in C# [duplicate] - c#

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
What is the C# Using block and why should I use it?
I have seen the using statement used in the middle of a codeblock what is the reason for this?

The using syntax can(should) be used as a way of defining a scope for anything that implements IDisposable. The using statement ensures that Dispose is called if an exception occurs.
//the compiler will create a local variable
//which will go out of scope outside this context
using (FileStream fs = new FileStream(file, FileMode.Open))
{
//do stuff
}
Alternatively you could just use:
FileStream fs;
try{
fs = new FileStream();
//do Stuff
}
finally{
if(fs!=null)
fs.Dispose();
}
Extra reading from MSDN
C#, through the .NET Framework common language runtime (CLR), automatically releases the memory used to store objects that are no longer required. The release of memory is non-deterministic; memory is released whenever the CLR decides to perform garbage collection. However, it is usually best to release limited resources such as file handles and network connections as quickly as possible.
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.

It is often used when opening a connection to a stream or a database.
It behaves like a try { ... } finally { ... } block. After the using block, the IDisposable object that was instantiated in the parenthesis will be closed properly.
using (Stream stream = new Stream(...))
{
}
With this example, the stream is closed properly after the block.

using is try finally syntaxical suger for anything that has an IDisposable.. like a sqlconnection. Its use it make sure something is disposed after its out of the using(){} scope.
using(SqlConnection conn = new SqlConnection(connString))
{
//use connection
}
//shorter than
SqlConnection conn = new SqlConnection(connString)
try
{
//use connection
}
finally
{
conn.Dispose();
}

The using statement ensures an object is properly disposed once it is nolonger required.
It basically saves you writing obj.Dispose(); and gives a visual guide as to the scope and usage of an variable.
See the MSDN page for more info

This form of using has to do with freeing resources. It can only be used in combination with class that implement the IDisposable interface.
example:
using(SqlConnection conn = new SqlConnection(someConnectionString))
{
//Do some database stuff here
}
at the end of the using block conn.Dispose is called, even if an exception was thrown inside the block. In the case of a SwqlConnection object means that the connection is always closed.
A drawback of this construction is that there is now way of knowing what happend.
Hope this helps answer your question?

Whenever your code creates an object that implements IDisposable, your code should do the creation inside a using block, as seen above.
There is one exception to this rule. An error in the design of WCF proxy classes prevents using statements from being useful for proxy classes. Briefly, the Dispose method on a proxy class may throw an exception. The WCF team saw no reason not to permit this.
Unfortunately, not seeing a reason doesn't mean that there is no reason:
try
{
using (var svc = new ServiceReference.ServiceName())
{
throw new Exception("Testing");
}
}
catch (Exception ex)
{
// What exception is caught here?
}
If the implicit Dispose call throws an exception, then the catch block will catch that exception instead of the one thrown within the using block.

Related

Nested Using Keyword for connection dispose.

I am using "using" Keyword in c#.
using(SqlConnection sourceConnection = new SqlConnection())
{
sourceConnection.Open();
var destinationConnection = new SqlConnection();
destinationConnection.Open();
}
In Above line of code is both the connections will dispose or only sourceConnection() will dispose.
Only sourceConnection, i.e. the object that you wrap in the using statement, will be disposed. You should use another using statement to make sure that destinationConnection is also disposed:
using (SqlConnection sourceConnection = new SqlConnection())
using (var destinationConnection = new SqlConnection())
{
sourceConnection.Open();
destinationConnection.Open();
}
using operates on the IDisposable interface. Ignoring the scoping of the variable, it basically does something a bit like this:
SqlConnection sourceConnection = new SqlConnection();
try
{
sourceConnection.Open();
var destinationConnection = new SqlConnection();
destinationConnection.Open();
}
finally
{
if (sourceConnection != null)
{
sourceConnection.Dispose();
}
}
So in answer to your question, it will only close one.
From MSDN via this post by Robert S.:
C#, through the .NET Framework common
language runtime (CLR), automatically
releases the memory used to store
objects that are no longer required.
The release of memory is
non-deterministic; memory is released
whenever the CLR decides to perform
garbage collection. However, it is
usually best to release limited
resources such as file handles and
network connections as quickly as
possible.
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.
Again this indicates that it only works on one object: the subject of the using.
As some people already noted, using wraps the IDisposable interface, as in:
using (var foo = new MyDisposable()) { ... }
is the same as:
var foo = new MyDisposable()
try {
...
}
finally {
if (foo != null) { foo.Dispose(); }
}
So far so good. The reason that C# implements this is because of unmanaged resources. Why? Unmanaged resources require you to clean up the stuff at a time you want, instead of a time that the Garbage Collector (GC) wants (which is f.ex. when you run out of memory).
Consider the alternative for a moment: let's assume you have a file. You open the file, write some bytes, forget 'close' and then don't have IDisposable to close it. Your file will continue to be open, even though you don't use the object anymore. Even worse, you don't even know that data has been written if your program exits. If your program runs long enough, at some point the GC will probably kick in and remove the thing for you, but until then every other attempt to open the file will probably give you a big, fat error. So, in short...: a lot of pain and misery.
And this is what IDisposable solves.
Connections, files, memory access, network access, ... basically everything that uses stuff that needs to be cleaned up implements IDisposable. It even holds true that if a type implements IDisposable, you'd better Dispose it.
So... SQL connections implement IDisposable, SQL Readers implement IDisposable, and so forth. Personally, I tend to check every type for the presence of an IDisposable interface, before working with it (so yeah that is: all the time).
Once you understand this, the correct way to use all this is obvious:
using (var sourceConnection = new SqlConnection())
{
sourceConnection.Open();
using (var destinationConnection = new SqlConnection())
{
destinationConnection.Open();
// ...
using (var myReader = srcConnection.ExecuteReader(...))
{
// ...
}
}
}
... and so on.
Now, in some cases you obviously cannot use using because you're using different methods. How to solve this? Easy: Implement the Dispose Pattern in the class that has these methods.
More information (as well as the Dispose pattern): https://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.110).aspx
Only one of them will be disposed, you're never explicitly calling Dispose or wrapping in a using the destinationConnection.
You could do this, and both will always dispose.
using(SqlConnection sourceConnection = new SqlConnection())
{
using(SqlConnection destinationConnection = new SqlConnection())
{
}
}

Will Db conneection get closed in following situaltion?

I have question on connection I create in C# code
To Read data I have written Factory Class for all the read which is as follows
Public static OracleDataReader(CommandType ct,string command,params OracleParameter[] cp)
{
OracleConnection cn = new OracleConnection(getconnection());
try
{
return ExecuteReader(cn,ct,command,cp);
}
catch
{
cn.close();
}
}
Now I use it as follows
qry = "select * from emp";
using(IDataReader dr = OracleFacoty.ExecuteReader(CommandType.Text,qry,null)
{
while(dr.read())
{
//Do operation
}
}
Now my question is, will the connection opened in factory method will be closed automatically or I Need pass the connection from calling method and close the connection once i am done with data read.
The using statement will dispose the dB connection properly when it's instantiated within it checkout this from msdn regarding this approach of like you did
You can instantiate the resource object and then pass the variable to the using statement, but this is not a best practice. In this case, the object remains in scope after control leaves the using block even though it will probably no longer have access to its unmanaged resources. In other words, it will no longer be fully initialized. If you try to use the object outside the using block, you risk causing an exception to be thrown. For this reason, it is generally better to instantiate the object in the using statement and limit its scope to the using block.
I would suggest probably use using and instantiate connection and pass that instance to your factory methods to perform any operations, by end the using will then properly dispose the database connection.
https://msdn.microsoft.com/en-us/library/yh598w02.aspx
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection(v=vs.110).aspx
By looking at your code, I can say
You have a static method in class which Creates new Connection each time you call it and returns some DataTable object(?)
Whenever an error occurs within ExecuteReader(), exception is suppressed and connection closes without questions.
But in Second snippet, you're not using OracleDataReader you're directly calling ExecuteReader() which, as I believe, will not handle any exceptions.
Also, in first snippet, connection closes only when an error occurs. If no error, connection will not close and will cause memory leaks and after some attempts it max outs connection limits.
If you need new connection for every call, then put the Cn.close() in finally{} block.

Handle Exception that happens within a using statement (IDisposable)

I'm using the DataWriter and DataReader interfaces.
These classes have the IDisposable interface implemented, therefore I wrap them around the using keyword:
using(var datareader = new DataReader(SerialPortInputStream))
{
CancellationTokenSource cancellation = new CancellationTokenSource();
//Timeout
cancellation.CancelAfter(1000);
//...
datareader.LoadAsync(120).AsTask(cancellation.Token);
//Some fancy methods
...
//Last step: Detach the InputStream to use it again
datareader.DetachStream();
}
This thread here is saying that if an Exception (here a "TaskCancelledException" happens inside a using statement, the object gets disposed. Now, the problem is with the UWP-DataReader and DataWriter: They will close the underlying stream if the object gets disposed. To prevent that I've to call datareader.DetachStream() and then dispose.
We cannot use the DataReader/DataWriter with a using statement when we need the underlying InputStream/Outputstream later again.
Is this conclusion correct or are there other ways to handle this situation?
The whole meaning of using is to make sure that the object gets disposed at the end of the block no matter what happens without having to write all the code for this by yourself. This is done by disposing the object inside a finally block.
What you are trying to do is to call datareader.DetachStream() before the object gets disposed - again no matter what happens.
So my conclusion would be that the using statement isn't very helpful here and you should do this by yourself, maybe like this:
DataReader datareader = null;
try
{
datareader = new DataReader(SerialPortInputStream);
CancellationTokenSource cancellation = new CancellationTokenSource();
//Timeout
cancellation.CancelAfter(1000);
//...
datareader.LoadAsync(120).AsTask(cancellation.Token);
//Some fancy methods
...
}
finally
{
//Last step: Detach the InputStream to use it again
datareader?.DetachStream();
datareader?.Dispose();
}
So this is essentially what the using statement does to your code, except that you can insert the datareader?.DetachStream() call.
Note that the datareader would eventually get disposed anyway even without the using statement. When the scope of this variable is left, the garbage collection may anytime decide to remove this instance from memory which would lead to a call to its Dispose method. So a call to DetachStream() is needed before leaving the scope.

If I have a connection in a using statement, will the connection be closed if an exception occurs in the using statement?

The following code doesn't have any sort of error handling.
I'm curious though. As it sits, will the connection that is created in the using statement be closed when the exception is thrown? Or will the connection remain open because it was never explicitly closed?
public override string ResetToDefault() {
string result;
using (var cn = HostFacade.GetDbConnection())
{
cn.Open();
DbProvider.Transaction = cn.BeginTransaction();
// Do something here that throws an unhandled exception.
DbProvider.Transaction.Commit();
cn.Close();
}
return result;
}
Edit: The connection being returned by HostFacade.GetDbConnection is an IDbConnection. It's safe here to assume it's being implemented as a SqlConnection object.
Yes, because a using statement is expanded by the compiler to be a try...finally block. Your code is the same as this:
SqlConnection cn = null;
try {
cn = HostFacade.GetDbConnection();
cn.Open();
// .. rest of the code here
}
finally {
if (cn != null)
cn.Dispose();
}
The Dispose call will close the connection.
The CLR guarantees that a finally block will execute.. except in very specific scenarios (such as a call to FailFast IIRC).
It depends on the implementation of Dispose() by the author of the specific library you are running.
Libraries built into the .NET Framework (like your example) will undoubtedly clean up the resources accessed, like the SqlConnection, but you should verify with documentation first, before assuming anything.

What happens if i return before the end of using statement? Will the dispose be called?

I've the following code
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
The dispose() method is called at the end of using statement braces } right? Since I return before the end of the using statement, will the MemoryStream object be disposed properly? What happens here?
Yes, Dispose will be called. It's called as soon as the execution leaves the scope of the using block, regardless of what means it took to leave the block, be it the end of execution of the block, a return statement, or an exception.
As #Noldorin correctly points out, using a using block in code gets compiled into try/finally, with Dispose being called in the finally block. For example the following code:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
effectively becomes:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
So, because finally is guaranteed to execute after the try block has finished execution, regardless of its execution path, Dispose is guaranteed to be called, no matter what.
For more information, see this MSDN article.
Addendum:
Just a little caveat to add: because Dispose is guaranteed to be called, it's almost always a good idea to ensure that Dispose never throws an exception when you implement IDisposable. Unfortunately, there are some classes in the core library that do throw in certain circumstances when Dispose is called -- I'm looking at you, WCF Service Reference / Client Proxy! -- and when that happens it can be very difficult to track down the original exception if Dispose was called during an exception stack unwind, since the original exception gets swallowed in favor of the new exception generated by the Dispose call. It can be maddeningly frustrating. Or is that frustratingly maddening? One of the two. Maybe both.
using statements behave exactly like try ... finally blocks, so will always execute on any code exit paths. However, I believe they are subject to the very few and rare situations in which finally blocks are not called. One example that I can remember is if the foreground thread exits while background threads are active: all threads apart from the GC are paused, meaning finally blocks are not run.
Obvious edit: they behave the same apart from the logic that lets them handle IDisposable objects, d'oh.
Bonus content: they can be stacked (where types differ):
using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{
}
And also comma-delimited (where types are the same):
using (SqlCommand comm = new SqlCommand("", conn),
comm2 = new SqlCommand("", conn))
{
}
Your MemoryStream object will be disposed properly, no need to worry about that.
With the using statement, the object will be disposed of regardless of the completion path.
Further reading...
http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
http://csharpfeeds.com/post/8451/Return_Within_a_Csharp_Using_Statement.aspx
Take a look at your code in reflector after you compile it. You'll find that the compiler refactors the code to ensure that dispose is called on the stream.

Categories

Resources