Unmanaged resources and Dispose()

Aparan picture Aparan · May 20, 2013 · Viewed 14.3k times · Source

I was reading some articles about Dispose() method and found that unmanaged resources should be freed explicitly from Dispose() method (or finalize() method) and the article says file handles and database connection objects are examples of unmanaged resources. Can anyone explain why those are unmanaged and what happens if not handled properly in Dispose()? I have no idea about what a file handle is. Where do they exist?

Answer

Matthew Watson picture Matthew Watson · May 20, 2013

In this context it's perhaps easiest to think of it like this:

  • An unmanaged resource is any resource that you obtained by making a Windows API call that returns a Windows Handle that must be freed at some point.

  • The only other kind of resource is memory. This is managed automatically if it was allocated by .Net. (Note that there are ways to allocate memory using the Windows API; this counts as an unmanaged resource.)

For example, the FileStream class calls the Windows API to open a file, for which FileStream keeps a file handle internally. That file handle represents an unmanaged resource that must be freed at some point.

FileStream uses the Windows API function CreateFile() behind the scenes. It is the handle returned from CreateFile which represents an unmanaged resource.

If you don't free those handles, they will remain allocated for the duration of the program, but all .Net classes that have an unmanaged resource provide a Finalizer (see below) to make sure that they will normally be freed at some point.

(But if you were writing your own file handling class and forgot to free the file handle anywhere at all, the file would remain open until your program exited.)

Normally such unmanaged resources will be freed in two places:

  • The Dispose() method. This should be the normal way that you dispose unmanaged resources.

  • The Finalizer. This is a last-resort mechanism. If a class has a finalizer it will be called by the Garbage Collector when it cleans up a dead object. Any class which has an unmanaged resource should have a finalizer to clean up if the programmer forgets to call Dispose().

This is somewhat of a simplification, but it will help you understand it I hope.

For full details, see this MSDN article on the Dispose Pattern.