tags:

views:

1177

answers:

14

Are there particular instances where I should (or shouldn't?) be using "using" blocks:

using(SomeType t = new SomeType()){
    ...
}
+27  A: 

When the SomeType class implements IDisposable.

Otávio Décio
using gets translated as:SomeType t = new SomeType();try{ ...}finally{ t.Dispose();}
consultutah
+7  A: 

Use using whenever the type implements IDisposable, unless you're going to wrap it in a try/catch block anyway, then you might as well (depending on what look you prefer) use a finally block.

bdukes
Even with a finally around, I think 'using' is preferable. When you see an object new'ed in a 'using' you know the dispose of it is taken care of. If there is no 'using', you have to scroll about and understand the control flow to convince yourself there isn't a leak. This takes unnecessary effort.
Scott Langham
+4  A: 

When SomeType implements IDisposable.

That is a clue to you the developer that SomeType uses unmanaged resources that need to be cleaned up.

mbeckish
+2  A: 

In this context the using statement is handy for types that implement IDisposable. When the code block exits the scope of the using statement, Dispose() is called implicitly. It's a good habit when working with objects you want to dispose immediately after use.

Dave Swersky
A: 

One situation is when you want to do something at the beginning of a code block, and then undo it at the end of the block, unconditionally (even if there is a throw).

The ctor for the disposable class that you build (and call within the using) would perform the action, and then the Dispose method would undo that action. This is typically how I use it.

Allen
That sounds like a lot of confusion waiting to happen for the next developer who needs to work on that code. Why wouldn't you use a (far more standard) "finally" block?
John Price
its what log4net does with using (NDC.Push("string"))The first call pushes and the dispose pops the item off the NDC stack
Allen
A: 

The primary rule is: * Use USING statement when objects implements IDisposable interface.

This interface provides the Dispose method, which should release the object's resources. If this method is not invoked then the object will stay in memory as long, as CLR wants to perform garbage collection. If the programmer use the USING statement then on the end the object will be disposed, and all resources will be free.

It is very important that all resources that are no longer in use be free as soon as possible.

For more information about it just visit this link: microsoft

rpf
could be worded a little clearer but thats not worth voting down
Allen
A: 

Other people has mentioned about "IDisposable" already.

But one of the caveats when using "using" statement is that, any exceptions thrown within "using" will not be caught even thought "SomeType" will be disposed regardless.

So in the following snippet,

using (SomeType t = new SomeType()){
    throw new Exception("thrown within using");
}

throw new Exception("thrown within using"); should not be disregarded.

Sung Meister
An exception gets caught by a catch handler, declared with the c# catch keyword. 'using' makes no difference to this. An exception thrown within a 'using' will be caught if there's an appropriate 'catch' handler.
Scott Langham
Oh, I see. You're saying the 'using' will ensure the Dispose method will still be called on 't' even if there is an exception thrown within the body of the using.
Scott Langham
Yes, Scott. That was my point, exactly.
Sung Meister
+2  A: 

Example:

        using(SqlConnection MyConnection = new SqlConnection("Connection string"))
        {
            MyConnection.Open();

            //...

            // 1. SQLConnection is a type that implements IDisposable
            // 2. So you can use MyConnection in a using statement
            // 3. When using block finishes, it calls Dispose method of 
            // SqlConnection class
            // 4. In this case, it will probably close the connection to 
            // the database and dispose MyConnection object

        }

You can create your own objects that implements IDisposable:

public class MyOwnObjectThatImplementsIDisposable : IDisposable
{

    //... some code

    public void Dispose()
    {
        // Put here the code you want to be executed when the
        // using statement finish.
    }
}

So you could use an object of MyOwnObjectThanImplementsIDisposable type in a using statement:

        using(MyOwnObjectThatImplementsIDisposable MyObject = new MyOwnObjectThatImplementsIDisposable)
        {

            // When the statement finishes, it calls the 
            // code you´ve writed in Dispose method
            // of MyOwnObjectThatImplementsIDisposable class
        }

Hope this helps

Javier Morillo
+5  A: 

Some objects need some action to be taken when you have finished with them. Usually this is because the object uses some kind of resource that needs to be disposed of. For example, if you have a file object of class File, and this object opens a file from the file system, the file in the file system will need to be closed again.

If you just left the file object, and forgot to call file.Close() it wouldn't be cleaned up until the Garbage Collector (GC) ran and worked out nothing was still using the file object. When the Garbage Collector runs should be left to the Common Language Runtime (CLR) to decide. If the GC doesn't run for quite a while after you have finished with the file, the file could remain open potentially for a long time. This can pose a big problem if there are many file objects, or if something wants to open a file, but can't because the file object you left is still hanging around.

To solve this problem, C# has the IDisposable interface. This has one method called Dispose. Classes that require some cleanup implement this Dispose method. This gives you a standard way for cleaning up any objects that use resources. There are a lot of classes that need to have Dispose called. The problem with this is that code gets covered with calls to Dispose, and they are tricky to follow because the place where you new'ed the object and call Dispose to clean it up are different. So, you had to look around the code a lot and be very careful to check there were calls to Dispose in the right place.

To solve this problem C# introduced the 'using' keyword. You can put a 'using' keyword around where you new an object, and this ensures Dispose will be called on it for you. It guarantees that Dispose will be called whatever happens... even if there is an exception thrown within the body of the using statement.

So, you should use 'using' when you want to be sure an object that allocates resources will be cleaned up.


using can only be used for objects that are declared on the stack, i.e. in a function. It doesn't work for objects that are declared as members of a class. For them, you have to call Dispose yourself. You may have to implement Dispose in your class so that in can call Dispose on any member objects it has that require it.


Common objects that need using called on them are: Files, Database connections, Graphics objects such as Pen and Brush.


Sometimes it is also used when you want two operations to happen together. For example if you want to write a log statement when a block of code is entered and when it exits you could write a log class that you could use like this:

using( Log log = new Log("Doing stuff") )
{
    // Stuff
}

The constructor for the log class could be made to write out the message, and the Dispose method could also write it out. Implement the finalizer (~Log) to assert if the Dispose method doesn't get called to ensure the 'using' is remembered around the 'new Log'.

Scott Langham
Great summary! +1
Cshift3iLike
Agreed. This is a great summary.
JohnnyO
+4  A: 

I see plenty of other answers indicated when you should have a using statement. I want to address when specifically should not have a using statement:

If you need to use your object outside of the scope of the current function, don't have a using block. Good example are a factory method that returns a database connection or a method that needs to return a datareader. In either of those cases if you create your object with a using statement it would be disposed before the method returned, and therefore not usable outside the method.

Now, you still want to be sure that those objects are disposed, so you still might want a using statement somewhere. Just don't include it in the method where the object is actually created. Instead, you can wrap the function call itself in a using statement.

Joel Coehoorn
+1  A: 

Maybe it is worth mentioning that underlying reason for adding “using” lo C# languge is following: some resources can be scarce enough that it doesn’t make sense to wait for GC to call IDisposable. For example, DB connections. If you use try/catch/finally you won’t end up with a dangling connection, but connection will be left hanging until GC doesn’t kick in and this can take a while (if you do not close it explicitly). IF you use "using" (excuse the pun) you will release the connection immediately even if you forgot to close it and even if some exception occured inside the using block.
Another reason, as previous post mentions, is that programmers do not always use finally to clean up. If not using finally in the case of exception you end up with leaking resources…

Dan
A: 

I would also add that use a using() statement if something implements IDispose and also if that something you want to dispose of holds on to NON-MANAGED resources like database connections and file handles.

If it's a normal object with say a List<T>, where T is like a Customer object that holds names and address, then you don't need to. The garbage collector is smart enough to manage this for you. But the garbage collector WILL NOT return connections to the connection pool or close file handles.

Chris
+1  A: 

One specific instance in which you should be careful using a using block is with a WCF Service Client.

As noted in this MSDN article, wrapping a WCF client (which does implement IDisposable) in a using block could mask any errors which result in the client being left in a faulted state (like a timeout or communication problem). Long story short, when Dispose() is called, the client's Close() method fires, but throws and error because it's in a faulted state. The original exception is then masked by the second exception. Not good.

There are various workarounds out there, including one in the MSDN article itself. Others can be found at IServiceOriented and blog.davidbarret.net.

I prefer the last method, myself.

Eric King
wow that is seriously scary. I've just been using the "using" statement when i need to open a connection.
Alex
A: 

If you want a summary rule. Anytime an object using IDisposable where you would not have a catch, use using. Using, essentially, is this pattern:

try { //instantiate and use object } finally { //dispose object }

If you do not need a catch, using can save you typing, which is a good thing.

Gregory A Beamer