0

I have DisposableObject is IDisposable. I know that it should be wrapped to the using or dispose is explicitly called.

public void Method()    
{
       var disposable = new DisposableObject();
}

But I have argued about this logic with some colleagues. Do you think that 'unhanled' Dispose method will be called on automatically by GC on some point?

Thanks for the answer.

Ievgen
  • 4,261
  • 7
  • 75
  • 124
  • 1
    It will be called when the object is dereferenced from all sources and the GC makes its next round. – Jeroen Vannevel Oct 22 '13 at 13:01
  • 2
    **No**, it'll call destructor (**finalizer**) not your Dispose() method. Inside finalizer usually implementations call the Dispose() method (if they follow Dispose pattern). – Adriano Repetti Oct 22 '13 at 13:01
  • 1
    @JeroenVannevel no, it won't call the Dispose() method but the finalizer (there implementation _may_ call Dispose()) – Adriano Repetti Oct 22 '13 at 13:01
  • 2
    No. You should read about `Finalizer` : http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx – Ahmed KRAIEM Oct 22 '13 at 13:01
  • 2
    Microsoft strongly recommends your finalizer call Dispose: http://msdn.microsoft.com/en-us/library/ms244737.aspx – Dan Oct 22 '13 at 13:03
  • 1
    read [this great answer about `IDisposable`](http://stackoverflow.com/a/538238/571637) several times... know it, love it, live it – jltrem Oct 22 '13 at 13:17

3 Answers3

4

Is in this case Dispose method will be called automatically by GC?

No. It will not call Dispose you have to call it yourself or use using block which will ensure its disposal even in case of an exception.

using(var disposable = new DisposableObject())
{
  //your code
}

IDisposable is used to ensure that unmanaged resources held by the application are released prior to garbage collection. Since GC can't release resources held by unmanaged resources like file handler.

Habib
  • 219,104
  • 29
  • 407
  • 436
1

No the GC does not call Dispose on disposable objects (objects implementing IDisposable). The GC manages object clean up by calling the finalizer (destructor) of managed objects. You implement a Dispose method if you want control when manage resources are freed (not if they are freed or not).

E.g If you have a class that has a TCPClient member then this is a managed object that controls a resource - the port its connected on. If you dont implement IDispose on your class and you use an instance off it then at some point when the GC sees the TCPClient is no longer used it will finalize that object and the port will be close - but you have no control over WHEN that will happen. If you need access to the port and a particlar time then you need to CONTROL WHEN its closed - in this case you can impliment IDispose and use a using statement or call Dispose directly yourself to ensure the resouce (port) is freed.

Ricibob
  • 7,505
  • 5
  • 46
  • 65
  • 1
    Just for clarity, for this to be true you must call `Dispose` in the finalizer: "If you don't implement IDispose on your class and you use an instance off it then at some point when the GC sees the TCPClient is no longer used it will finalize that object and the port will be close" – jltrem Oct 22 '13 at 14:31
1

If a class overrides a method called Finalize and an instance of that class is found to have been abandoned without GC.SuppressFinalize() having been called upon that instance, the GC will store a reference to the object in a list of things whose Finalize should be run ASAP (temporarily resurrecting it) and mark the object so that the next time it's abandoned it will simply disappear. If any objects have been placed on the list for immediate finalization, the GC will then launch a thread to run their Finalize methods.

For whatever reason, the creators of C# decided to confuse things a little bit by forbidding programmers from overriding Finalize directly and instead requiring that programmers wishing to override Finalize use a construct they call a "destructor", with syntax reminiscent of a C++ destructor, but totally different semantics. Although C# adds a little bit of wrapper code, one can generally think of ~className {whatever} as being roughly equivalent to overriding Finalize.

Microsoft recommends that if one overrides Finalize (or implements a C# destructor), that override/destructor should simply call a method with signature void Dispose(bool), passing False for the parameter value. It based upon that advice that people get the idea that the GC calls Dispose. Note that the GC itself doesn't call Dispose; note further that most objects shouldn't implement C# destructors nor override Finalize in any other way. Unless one understands all the corner cases involved with Finalize, it's generally better to ensure that IDisposable.Dispose gets called before objects are abandoned.

supercat
  • 77,689
  • 9
  • 166
  • 211