SYSK 53: To Close() or to Dispose()? That is the question…

Since I’m still meeting developers that are not quite sure of the differences between the two, and the choice that’s right for them, I decided to blog on the topic…

Just so we are all on the same page, you need to call Close or Dispose methods to release non-memory resources, e.g. handles, connections, etc., before the non-deterministic garbage collection does its job.  We all know the golden scalability rule – acquire resources as late as possible and release them as soon as possible…

Of course, if you only have one or the other, it’s an easy decision.  You know you need to call the Close method on Microsoft.Win32.RegistryKey object to release the resources since Dispose is not an option.

But there are a number of classes in .NET, and in some third party products, that have both – Close and Dispose methods.  Examples include System.Data.IDbConnection implementations (e.g. SqlConnection), System.IO.MemoryStream, System.IO.FileStream, System.IO.IsolatedStorage.IsolatedStorageFile, etc.) 

Here is an easy to remember rule I use:  if you plan to reuse the same instance of the object, then call Close(); otherwise call Dispose().   For example, in the following pseudo-code I’d get a run time exception if I were to use Dispose instead of Close:

SqlConnection cn = new SqlConnection(“connection string”);
cn.Open();
// Do some db work
cn.Close();

// Do a lot more non-db work

cn.Open(); // here is where an exception would be thrown if I disposed instead of closing the connection.
. . .

Arguably, this method should be broken into two or three methods with their own instances of SqlConnection class, in which case I’d call Dispose, which will close the connections for me…

Rule of thumb: favor Dispose over Close.   Why?  For three reasons:
1.  Dispose implementation will clean up all its resources…   Who knows, may be there is some class that, underneath the covers, uses several resources that all need to be released.  Close may only release the exposed underlying resource…
2.   Dispose is a .NET implementation of IDisposable interface.  One could say that Close is legacy…
3.  Forces you to be a better (more modular) programmer (see example above).