2

Does the Dispose method use Garbage collector to clear resources?
Also is there any benefit in using Dispose instead of finalizers?
I have searched for answeres but nothing very good at explaining it so far.
Thank you.

Marco
  • 56,740
  • 14
  • 129
  • 152

4 Answers4

3

Dispose() is a regular method.
It has nothing to do with the garbage collector.

Calling methods like Dispose() allow you to release unmanaged resources that the garbage collector doesn't know about, like native file handles.
You should also do that in a finalizer, so that they won't leak if your callers forget to call Dispose(). However, calling Dispose() allows them to be released immediately, as opposed to waiting for the garbage collector to dispose your object.

If your object holds other objects that in turn have unmanaged resources, you should implement Dispose() but not a finalizer. Dispose() allows your callers to immediately dispose the deeper unmanaged resources, but you don't have anything for a finalizer to do. (the unmanaged resources should be released by the inner finalizers)

To implement this cleanly, use the Dispose(disposing) pattern, which cleanly delineates where to dispose managed and unmanaged resources.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • So you are basically saying I should just use Dispose () and not GC as there would be no real reason for me to implement GC? GC would get implemented automatically. –  Dec 03 '13 at 15:05
  • 1
    correct. implement the correct patterns and GC will take care of itself. – Mike Beeler Dec 03 '13 at 15:31
  • 1
    @EPOColla: You cannot implement or interact with the GC at all. – SLaks Dec 03 '13 at 15:39
  • Thanks for your help in helping my understanding. However what about gc.collect? is that not interacting with the GC? –  Dec 03 '13 at 15:57
2

Does the dispose () method use Garbage collection to clear resources?

No. Dispose() is used for releasing unmanaged resources (usually). It doesn't have anything to do with GC.

See: IDisposable interface

The primary use of this interface is to release unmanaged resources. The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used. However, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.

Garbage collector calls the finalizer (destructor) of an object and if that object implements IDisposable then the finalizer can have a call to Dispose(false)

Habib
  • 219,104
  • 29
  • 407
  • 436
  • Thank you for your reply. So I should always automatically choose using instead of Finalizer because Garbage collection should be automated? –  Dec 03 '13 at 14:50
  • 1
    @EPOColla, if an object implements `IDisposable` then use it with `using` or call `Dispose` to release unmanaged resources, [*except `Task` class*](http://blogs.msdn.com/b/pfxteam/archive/2012/03/25/10287435.aspx). – Habib Dec 03 '13 at 14:52
  • I only learned now that GC is more for unmanaged resources, So it makes more sense now. I will probably have less reason use Finalizer if it's for managed resources. Thanks –  Dec 03 '13 at 14:56
  • 1
    @EPOColla, no GC is for Managed resources, `IDisposable` interface or Dispose Pattern is for releasing Unmanaged resources. Garbage Collector can't/won't do anything with unmanaged resources. – Habib Dec 03 '13 at 14:57
  • Is there any reason I would have to call GC.Collect() when I could just use using? Thanks. –  Dec 03 '13 at 15:02
  • @EPOColla, don't call `GC.Collect`, you don't need it. Let Garbage Collector work on its own, with `using` statement you ensure releasing of unmanaged resources, which has nothing to do with GC – Habib Dec 03 '13 at 15:24
0

Some objects, in order to behave as specified, need outside entities to do things on their behalf. In some cases, outside entities will be able to do everything that's necessary before a method returns. In other cases, however, a method will need to return after having asked an outside entity keep doing something until further notice (but without having given it such notice). The object thus acquires a responsibility to let the outside entity know when its services are no longer required.

The purpose of IDisposable is to provide a standardized way by which an object can be told "Your services will no longer be required, so if you've asked any outside entities to start doing something on your behalf so you could in turn use it to satisfy your customers, you should tell them to stop doing so." It generally does not free up any memory (except in cases where an outside entity has reserved some memory to help it satisfy the object's needs), and in many cases need not actually do anything (if no outside entities are doing anything on behalf of some object, nobody will need to be told to stop acting on its behalf).

Finalizers exist primarily to deal with the possibility that objects which implement IDisposable might get abandoned without their dispose method having been called. It effectively tells an object "It looks as though you've been abandoned, so you should probably clean up". Although Finalize can serve as a "safety net", it should not be considered reliable; generally, if an object which has a finalizer is wrongfully abandoned, the finalizer will get run "sometime", but there's generally no guarantee of timeliness. Thus, when an object which has asked an entity to do something on its behalf is no longer needed, it should be told immediately (via Dispose) rather than abandoned. In a properly-written program, few finalizers should ever run.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Lots of answers here focusing on freeing UNmanaged resources - which is indeed a role of Dispose. Howerver important to note that this case (of having to deal with raw manged resources, i.e os file handles, socket handles etc) is very rare. In almost all cases we deal with these resources via MANAGED objects - that themselves implement IDisposable to free their resources.
So in reality the common reason for writing dispose is not about WHAT resources are freed but rather WHEN resources are freed. I.e in general we write Dispose because our objects contains (managed) members that control resources (eg TCPClient that holds open a socket). By implimenting IDispose we allow users of the our class to control WHEN that MANAGED resource is freed - either by applying a using statement or by explicitely calling Dispose.

Ricibob
  • 7,505
  • 5
  • 46
  • 65