36

StreamReader class has both close and dispose method. I want to know which method to call to clean up all resources.

If making use of using block, I think it will call its dispose method. Will it be enough to clean up all the resources.

user496949
  • 83,087
  • 147
  • 309
  • 426

6 Answers6

30

The using block will call Dispose() on the StreamReader instance. Generally speaking, if a type is IDisposable, you should put it in using scope.

EDIT: If you look at the Close() implementation of StreamReader using Reflector, you will see that it's calling Dispose(true). So if you're not using the using scope, calling Close() manually would be the same as calling Dispose() in this particular case.

protected override void Dispose(bool disposing)
{
    try
    {
        if ((this.Closable && disposing) && (this.stream != null))
        {
            this.stream.Close();
        }
    }
    finally
    {
        if (this.Closable && (this.stream != null))
        {
            this.stream = null;
            this.encoding = null;
            this.decoder = null;
            this.byteBuffer = null;
            this.charBuffer = null;
            this.charPos = 0;
            this.charLen = 0;
            base.Dispose(disposing);
        }
    }
}
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • 1
    close calls dispose(true), will using block also call dispose(true)? – user496949 Nov 11 '10 at 11:02
  • 1
    This explains why if you have code inside a `using` with a call to `Close()`, upon running Visual Studio's Code Analysis you will get `CA2202 Do not dispose objects multiple times` - because `Close()` already disposes, and `using` will eventually try disposing the object, again. I wonder, then... why we do not really face `System.ObjectDisposedException`. – Veverke Jul 07 '16 at 14:47
  • @Veverke, Close disposes the object but does not mark as disposed that is why it doesn't throw System.ObjectDisposedException. – Anoop H.N Jun 15 '23 at 09:59
7

We all know System.IO.StreamReader is not the only .NET 4.0+ class that implements IDisposable and a Close() method. For the case of StreamReader in this question, the source code shows that the base class TextReader.Close(), TextReader.Dispose() both run the same lines of code. You can also see in the code that TextReader.Dispose() is the implementation for when you call StreamReader.Dispose() (because StreamReader doesn't override that method overload signature of Dispose).

So a call to StreamReader.Dispose() will run this inherited line of code, which calls the protected override method StreamReader.Dispose(disposing: true) and so will StreamReader.Close() call StreamReader.Dispose(disposing: true). So for the case of StreamReader, Close() and Dispose() do happen to run the same lines of code.

A more general, non-class-specific answer to the question of Close() or Dispose()?, might be to note that Microsoft has fairly clear documentation on implementing IDisposable and the Dispose pattern. A quick read is enough to show you that implementing a Close() method is not a requirement of the Dispose pattern.

imho the reason for finding the method Close() on so many classes that implement IDisposable, is the result of convention, not requirement.

Someone commented

Close and Dispose - which to call?

An example of another class that implements IDisposable with the Dispose pattern, and has a Close() method. Does Close() run the same code as Dispose() in this case? I haven't looked at the source code, but I'd say not necessarily.

Community
  • 1
  • 1
T. Webster
  • 9,605
  • 6
  • 67
  • 94
2

Use Dispose via a using block to guarantee that clean-up happens.

Use Close if you finish with the object considerably before the end of the using block, to be as prompt as possible in releasing any resources.

The two will hence work hand-in-hand, though the latter can be redundant if you are going to reach the end of the block in a few nanoseconds anyway.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
1

The using block is all that you need.

Stefan P.
  • 9,489
  • 6
  • 29
  • 43
  • Using will guarantee to call dispose. Is it same as calling close? – user496949 Nov 11 '10 at 10:51
  • dispose will implicit close the stream – Stefan P. Nov 11 '10 at 10:52
  • ...unless you write "complex" code with long-lived objects. Better advice would be: use using if syntactically possible. Else handle the complexity that the programming world dealt with since the invention of memory allocation like a big kid--carefully. – Eliot Gillum Aug 29 '19 at 04:14
1

If you want further information about using, take a look here

Using

Quote from site:

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.

Neil Knight
  • 47,437
  • 25
  • 129
  • 188
1

There appears to be some concern about whether Dispose actually does its job properly.

Essentially - you can be fairly certain that anything in the BCL(Base Class Library) which implements IDisposable will tidy itself up properly when dispose is called - such as when a using statement goes out of scope.

If there were issues with streams not being closed they would have been picked up by now - you can trust IDisposable. It's when you're using other libraries that you rely on the Dispose implementation.

David Neale
  • 16,498
  • 6
  • 59
  • 85