11

My .net service cleans up all its unmanaged resources by calling resourceName.Dispose() in a finally block before the Main() loop exits.

Do I really have to do this?

Am I correct in thinking that I can’t leak any resources because the process is ending? Windows will close any handles that are no longer being used, right?

s d
  • 2,666
  • 4
  • 26
  • 42

2 Answers2

9

It's probably okay to skip this, in that specific case.

The first thing to understand is that while ending the process should by itself be enough to cleanup most things, it's possible for some unmanaged resources to be left in a bad or unclosed state. For example, you might have an app that is licensed per seat, and when the app closes you need to update a database record somewhere to release your license. If a process terminates incorrectly, nothing will make that update happen, and you could end up locking people out of your software. Just because your process terminates isn't an excuse not to do cleanup.

However, in the .Net world with the IDisposable pattern you can get a little more insurance. When the process exits, all remaining finalizers will run. If the Dispose() pattern is implemented properly (and that's a bigger "if" than it should be), the finalizers are still there to take care of any remaining unmanaged resources for their objects...

However, it's good practice to always be in the habit of correctly disposing these things yourself. And FWIW, just calling .Dispose() is not enough to do this correctly. Your .Dispose() call must be included as part of a finally block (including the implicit finally block you get with a using statement).

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 1
    That's the key though, "*if* the `Dispose()` pattern *is implemented properly*". Since this is not guaranteed, it's best to always dispose `IDisposable` objects yourself, as you suggested. – moribvndvs Oct 25 '12 at 21:35
  • 2
    While this specific case may be okay, it's a bad habit to encourage. You never know when that code may be subject to R&D (Rip-off and Deploy) into another project and then bad things could happen. Do this small bit right every time and you'll never have to worry. – Jesse C. Slicer Oct 25 '12 at 21:41
  • Just because a class implements IDisposable, doesn't mean it will also have a finaliser, typically Dispose is to clean up managed and unmanaged resources (if the class has any) and the finaliser is to just tidy up unmanaged resources that could leak memory if not tidied up. – Trevor Pilley Oct 25 '12 at 21:48
  • My counterpoint to the “it’s a bad habit” argument is “don’t write code you don’t need” Having said that, the idea of not cleaning up resources made me feel odd, which is why I asked the question in the first place :) – s d Oct 25 '12 at 21:50
  • @st: To relieve you of your concern. You *do* need to dispose of the object, it is not optional. The fact that finalizers are called can be thought of as an implementation detail from a language standpoint. That is designed to provide support for instances where your code can't know when to dispose of the object. – Guvante Oct 25 '12 at 21:53
  • Forgive my bluntness but: the process is ending why do I need to dispose of the object? – s d Oct 25 '12 at 21:54
  • @st Because the object may have unmanaged resources that could potentially not be cleaned up, even if the process is ended. That could result in resources being starved, etc. – moribvndvs Oct 26 '12 at 08:26
9

There is no limit to the types of resources that may be encapsulated by an object implementing IDisposable. The vast majority of resources encapsulated by IDisposable objects will be cleaned up by the operating system when a process shuts down, but some programs may use resources the operating system knows nothing about. For example, a database application which requires a locking pattern that isn't supported by the underlying database might use one or more tables to keep track of what things are "checked out" and by whom. A class which "checks out" resources using such tables could ensure in its Dispose method that everything gets checked back in, but if the program shuts down without the class having a chance to clean up the tables, the resources guarded by that table would be left dangling. Since the operating system would have no clue what any of those tables mean, it would have no way of cleaning them up.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • 2
    I think this answer makes the most sense: the OS can't release resources that it doesn't know about. – s d Oct 28 '12 at 18:38