2

Possible Duplicate:
What is the C# Using block and why should I use it?

So I've just noticed that at msdn examples and some stackoverflow questions there were answer where the using statement is used before the streamwriter etc, but what is actually the benefit? Since I've never been taught/told/read any reason to use it.

            using (StreamReader sr = new StreamReader(path)) 
            {
                while (sr.Peek() >= 0) 
                    Console.WriteLine(sr.ReadLine());
            }

Instead of:

            StreamReader sr = new StreamReader(path);
            while (sr.Peek() >= 0) 
                Console.WriteLine(sr.ReadLine());
Community
  • 1
  • 1
Random IT Guy
  • 625
  • 1
  • 8
  • 16

4 Answers4

6

The using block calls the Dispose method of the object used automatically, and the good point is that it is guaranteed to be called. So the object is disposed regardless of the fact an exception is thrown in the block of statements or not. It is compiled into:

{
    StreamReader sr = new StreamReader(path);
    try
    {
        while (sr.Peek() >= 0) 
            Console.WriteLine(sr.ReadLine());
    }
    finally
    {
        if(sr != null)
            sr.Dispose();
    }
}

The extra curly braces are put to limit the scope of sr, so that it is not accessible from outside of the using block.

Sina Iravanian
  • 16,011
  • 4
  • 34
  • 45
  • It is actually compiled into a try-finally block. – Daniel Hilgarth Jan 31 '13 at 23:37
  • @DanielHilgarth absolutely. I was editing the answer. – Sina Iravanian Jan 31 '13 at 23:39
  • Accept this answer! But be careful not to return a disposed object for example, a bitmap. I see that happening a lot. – User 12345678 Jan 31 '13 at 23:46
  • Their is no such thing as a guarantee - just pull the plug. Situations where this matters are admittedly quite rare but they do exist. Also note that this is a simplification - the code that is actually generated can not be translated to C# (besides using a `using` block). – Daniel Brückner Jan 31 '13 at 23:51
  • @ByteBlast What would happen if that happens? – Random IT Guy Jan 31 '13 at 23:51
  • @DanielBrückner Thanks for your comment. Can you forward me to some of such situations? I was involved with some memory leak issues recently, and I'm interested in knowing more about these. Thanks. – Sina Iravanian Jan 31 '13 at 23:54
  • @SinaIravanian Pretty sure there should be a null check int he finally block? – User 12345678 Jan 31 '13 at 23:55
  • @ByteBlast What would happen when you return an disposed object? Besides some kind of error? – Random IT Guy Feb 01 '13 at 00:00
  • @ByteBlast Yes, thanks for that. Also the scope of `sr` must have been limited so I added the extra braces around the whole statement. – Sina Iravanian Feb 01 '13 at 00:00
  • 1
    @CSharpStudent it depends on how `IDisposable` is implemented. It usually frees the resources used. In our `StreamReader` example trying to read from the stream again, would result in an exception of that kind. Note that a disposed object is different from a `null` object. – Sina Iravanian Feb 01 '13 at 00:03
  • @Sina How did you notice the memory leak? I've never even considdered checking for it, since most programs were just made in class etc.. – Random IT Guy Feb 01 '13 at 00:10
  • 1
    @CSharpStudent Well, first you notice some symptoms, such as excessive slowness, and so on. Then you use a profiler (such as RedGate's ANTS Memory Profiler) and you see that some big objects are never garbage collected or disposed of. – Sina Iravanian Feb 01 '13 at 00:16
  • @Sina Iravanian I meant if you are for example controlling a nuclear power plant you should definitely not rely on `Dispose()` being *always* called when using a `using` block. If someone unplugs the computer or spills some coffee over it you are out of luck. – Daniel Brückner Feb 01 '13 at 01:02
  • 1
    There is another detail to the code - in an using block it is not valid to perform an assignment to the variable holding the disposable object while in the code above nothing prevents changing the value of `sr` from inside the `try` block. – Daniel Brückner Feb 01 '13 at 01:03
2

The using provides a convenient syntax that ensures the correct use of IDisposable objects. It is compiled into:

StreamReader sr = new StreamReader(path);
try 
{
    while (sr.Peek() >= 0) 
        Console.WriteLine(sr.ReadLine());
} finally
{
    sr.Dispose();
}

As documented on MSDN

Alistair
  • 1,064
  • 8
  • 17
1

using statement works on stuff that implement IDisposable interface.

.net will garantee that the StreamReader will be disposed.

You don't have to worry about closing or managing it further: just use what you need inside the "using" scope.

Morv
  • 355
  • 2
  • 9
1

It automatically calls the StreamReader.Dispose() method for you. If you choose not to use the using keyword, you end up with an open stream after you run your code block. This is beneficial if you want to reserve a file (etc) for continued use, but could be bad practice if you do are not going to manually dispose of it when finished.

Aaron Campbell
  • 562
  • 8
  • 19