views:

145

answers:

9

What is better, the using directive, or the dispose directive when finished with an object?

 using(FileStream fileStream = new FileStream(
            "logs/myapp.log",
            FileMode.Open,
            FileAccess.Read,
            FileShare.ReadWrite))
        {
            using(StreamReader streamReader = new StreamReader(fileStream))
            {
                this.textBoxLogs.Text = streamReader.ReadToEnd();
            }
        }

On the other hand, when I'm dealing with System.Net.Mail, I'm told I need to Dispose() of the object to release any stray locks.

Is there any consistent guidance? How do I tell what is more appropriate in a given situation for a given object?

+2  A: 

using calls Dispose upon exit. using is better because it assures calling dispose.

Russ
+2  A: 

using blocks automatically call Dispose() when the end of the block is reached.

Bernard
+7  A: 

The using statement (not directive) involves an implicit call to Dispose(), in a finally block. So there is no contradiction here. Can you link to that discussion?

The official definition of
using (x) { ... }
is
try ... finally if (x != null) x.Dispose(); }

What is better?

From a notational perspective, the using() { } block. Technically they are the same.

Henk Holterman
Not exactly - your `x.Dispose()` is actually expanded as `((IDisposable)x).Dispose()` to handle the cases where the `IDisposable` `Dispose()` method is explicitly implemented.
Jesse C. Slicer
@Jesse: Yes, you're right. I consider my code a simplification.
Henk Holterman
The discussion was part of an email thread I got during a Microsoft Premier case, I can't forward it. The case revolves around using CDO though C# and although it works through COM-Interop it's unsupported by MSFT
MakerOfThings7
@Maker: Then I think your question isn't about `using` or `Dispose()` but about how/if to release (clean up) COM objects.
Henk Holterman
@Henk Holterman What is the difference between using/dispose versus COM cleanup? I'm ready to learn
MakerOfThings7
@MakerOfThings - COM objects do not implement IDisposable, because IDisposable is a .NET interface, and COM is not .NET. If you're working directly with a COM object, you should try `Marshal.ReleaseComObject` to destroy it.
Joel Mueller
@MakerOfThings7: Typically COM objects are wrapped in C# objects. The wrapper will remove the COM reference for you on `Dispose()`.
jdv
+4  A: 

It's the same thing. Usage is simple, if you create the object and use it in only one method then use using. If you need to keep it alive beyond the method call then you have to use Dispose().

The runtime callable wrappers for COM objects don't have a Dispose() method.

Hans Passant
@Hans Passant Are there any special provisions I need for COM objects?
MakerOfThings7
That's a loaded question, there are gazillions of them. If you can just add the reference to it, then no, unlikely. The finalizer thread takes care of them.
Hans Passant
@MakerOfThings7: You have to explicitly release all resources that your COM object may have acquired. Exactly how you do that depends on the COM object you're dealing with.
Eric J.
That's not how COM works, the object is responsible for resource management. Necessarily so, you cannot possibly guess what it used.
Hans Passant
+2  A: 
using(foo) 
{
    foo.DoStuff();
}

is just syntactic sugar for this:

try
{
    foo.DoStuff();
}
finally
{
    if(foo != null)
        foo.Dispose();
}

So I'm not sure where the debate comes from. using blocks do call dispose. Most people prefer using blocks when possible as they are cleaner and clearer as to what is going on.

Matt Greer
Not exactly - your foo.Dispose() is actually expanded as ((IDisposable)foo).Dispose() to handle the cases where the IDisposable Dispose() method is explicitly implemented.
Jesse C. Slicer
@Jesse, ah yes, good point. I forgot about explicit implementation.
Matt Greer
+2  A: 

As long as the lifetime of the object is within a block of code, use using, if your object needs to be long lived, for example to be disposed after an asynchronous call you need to manually call Dispose.

A using block is way better than you of remembering the call to Dispose in all possible and impossible ways execution can leave a block of code.

Albin Sunnanbo
+2  A: 

There's no reason that I can think of to manually call Dispose(), other than in another implementation of Dispose() (for example in a class you've created that implements IDisposable) when you can wrap an object in a using block. The using block puts the creation and disposal of the object in a try/catch/finally block to pretty much gaurantee that the object will be disposed of correctly.

The compiler is more reliable than me. Or you. =)

MSDN documents the using statement and calls out where you can obtain the C# language specification where you can review section 8.13 "The using statement" (at least in the v4.0 reference it's 8.13) that gives a comprehensive explanation of the using statement and how to use it. The fifth paragraph gives the following:

A using statement is translated into three parts: acquisition, usage, and disposal. Usage of the resource is implicitly enclosed in a try statement that includes a finally clause. This finally clause disposes of the resource. If a null resource is acquired, then no call to Dispose is made, and no exception is thrown.

Rob
Here's one: disposing private member objects in your own class's `Dispose()` implementation
recursive
@recursive, good point, no idea how that one slipped my mind. Momemtary dissapearance of my brain I have to assume! =) Fixed now though.
Rob
Here's another, disposing private members (or `this`) because your code is at a point where it can safely clean up everything ahead of time, with potential gains in efficiency and more importantly safety (if calling code fails to call dispose) even though the object externally appears to be "live". Still internal and not where `using` is applicable though.
Jon Hanna
+1  A: 

There is one really important reason to use the "using statement" anywhere you can.

If the code that wrapped via using statement threw an exception, you could be sure that the "using object" would be disposed.

madcyree
A: 

thanks good info

That's a comment, not an answer.
djacobson