How to: Execute Cleanup Code Using finally (C# Programming Guide)
The purpose of a finally statement is to ensure that the necessary cleanup of objects, usually objects that are holding external resources, happens immediately, even if an exception is thrown. One example of such cleanup is calling Close on a FileStream immediately after use instead of waiting for the object to be garbage collected by the common language runtime, as follows:
static void CodeWithoutCleanup() { System.IO.FileStream file = null; System.IO.FileInfo fileInfo = new System.IO.FileInfo("C:\\file.txt"); file = fileInfo.OpenWrite(); file.WriteByte(0xF); file.Close(); }
To turn the previous code into a try-catch-finally statement, the cleanup code is separated from the working code, as follows.
static void CodeWithCleanup() { System.IO.FileStream file = null; System.IO.FileInfo fileInfo = null; try { fileInfo = new System.IO.FileInfo("C:\\file.txt"); file = fileInfo.OpenWrite(); file.WriteByte(0xF); } catch(System.Exception e) { System.Console.WriteLine(e.Message); } finally { if (file != null) { file.Close(); } } }
Because an exception can happen at any time within the try block before the OpenWrite() call, or the OpenWrite() call itself could fail, we are not guaranteed that the file is open when we try to close it. The finally block adds a check to make sure the FileStream object is not null before calling the Close method. Without the null check, the finally block could throw its own NullReferenceException, but throwing exceptions in finally blocks should be avoided if possible.
A database connection is another good candidate for being closed in a finally block. Because the number of connections allowed to a database server is sometimes limited, it is important to close database connections a quickly as possible. If an exception is thrown before you can close your connection, this is another case where using the finally block is preferable to waiting for garbage collection.
CSTeam edit: This was fixed in later versions of the topic.
- 7/19/2007
- Licco
- 7/9/2010
- SJ at MSFT
But it might make sense to make a note to use a using statement when dealing with a database connection / class.
Assume you've written a DAL (Data Access Layer) and you want to use this object to call a sproc or perform some sort of CRUD operation. You should do this:
using (SQLDatabase d = new SQLDatabase())
{
//d is a database connection
//it implements IDisposeable
//do something with d
}
By using a using statement you ensure all allocated resources are released without having to remember the finally statement.
Just worth nothing
- 2/14/2010
- Jon Hermiz