Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For Microsoft built classes that inherit IDisposable, do I explicitly have to call Dispose?

Regarding the Microsoft built classes that inherit IDisposable, do I explicitly have to call Dispose to prevent memory leaks?

I understand that it is best practice to call Dispose (or better yet use a using block), however when programming, typically I don't always immediately realise that a class inherits from IDisposable.

I also understand that Microsoft implementation of IDisposable is a bit borked, which is why they created the article explaining the correct usage of IDisposable.

Long story short, in which instances is it okay to forget to call Dispose?

like image 940
Matthew Avatar asked Dec 02 '22 00:12

Matthew


2 Answers

There are a couple of issues in the primary question

Do I explicitly have to call Dispose to prevent memory leaks?

Calling Dispose on any type which implements IDisposable is highly recomended and may even be a fundamental part of the types contract. There is almost no good reason to not call Dispose when you are done with the object. An IDisposable object is meant to be disposed.

But will failing to call Dispose create a memory leak? Possibly. It's very dependent on what exactly that object does in it's Dispose method. Many free memory, some unhook from events, others free handles, etc ... It may not leak memory but it will almost certainly have a negative effect on your program

In which instances is it okay to forget to call Dispose?

I'd start with none. The vast majority of objects out there implement IDisposable for good reason. Failing to call Dispose will hurt your program.

like image 194
JaredPar Avatar answered Dec 18 '22 07:12

JaredPar


It depends on two things:

  1. What happens in the Dispose method
  2. Does the finalizer call Dispose

Dispose functionlity
Dispose can do several type of actions, like closing a handle to a resource (like file stream), change the class state and release other components the class itself uses.
In case of resource being released (like file) there's a functionality difference between calling it explicitly and waiting for it to be called during garbage collection (assuming the finalizer calls dispose).
In case there's no state change and only components are released there'll be no memory leak since the object will be freed by the GC later.

Finalizer
In most cases, disposable types call the Dispose method from the finalizer. If this is the case, and assuming the context in which the dispose is called doesn't matter, then there's a high chance that you'll notice no difference if the object will not be disposed explicitly. But, if the Dispose is not called from the finalizer then your code will behave differently.

Bottom line - in most cases, it's better to dispose the object explicitly when you're done with it.

A simple example to where it's better to call Dispose explicitly: Assuming you're using a FileStream to write some content and enable no sharing, then the file is locked by the process until the GC will get the object. The file may also not flush all the content to the file so if the process crashes in some point after the write was over it's not guaranteed that it will actually be saved.

like image 31
Elisha Avatar answered Dec 18 '22 05:12

Elisha