Software Development

Ensure object cleanup in your .NET applications

Recognizing the need to call and use the dispose method is essential to developing applications that perform properly. This article outlines the steps you should follow to ensure appropriate object cleanup in a .NET application.

Garbage collection in the Microsoft .NET common language runtime (CLR) environment absolves developers from tracking memory usage and knowing when to free memory. However, developers still need to stay abreast of an object's lifetime, thus being aware of when the object is no longer used. This article outlines the steps you should follow to ensure appropriate object cleanup in a .NET application.

Take out the trash

While garbage collection is automatic within the .NET CLR, it only processes objects that are ready for garbage collection. The system tracks objects and determines which objects are no longer in use; this process can be enhanced by signaling which objects are no longer being used. This entails calling an object's dispose method.

The dispose method is used for all tasks associated with freeing resources held by an object or preparing an object for reuse. It tells the CLR that the associated object is ready for garbage collection, and it releases all external resources used by the object (such as window handles or HWND, database connections, etc.).

Perusing the .NET Framework classes reveals that many of them include a dispose method. For example, the following classes include the method:

  • SqlConnection
  • SqlCommand
  • SqlDataReader
  • Timer
  • EventLog
  • Font

When utilizing these objects in your code, you should call the dispose method when they're no longer needed so the resources used by the objects are returned to the system. The following VB.NET code sample shows how it may be used when working with a SQL Server connection:

Dim conn As SqlConnection
Dim comm As SqlCommand
Dim dr As SqlDataReader
conn = New SqlConnection()
comm = New SqlCommand()
conn.ConnectionString = "data source=test;user id=test;password=test"
comm.CommandText = "SELECT * FROM test
comm.CommandType = CommandType.Text
comm.Connection = conn
conn.Open()
' Do something with the database
conn.Close()
conn.Dispose()
comm..Dispose()
dr.Close()

The code connects to a SQL Server database by creating connection, command, and datareader objects. The connection is closed when you're finished working with the database, and the dispose methods are called for all objects involved in the process. The code has a similar appearance when written in C#:

SqlConnection conn = null;
SqlCommand comm = null;
SqlDataReader dr = null;
conn = new SqlConnection();
comm. = new SqlCommand();
conn.ConnectionString = "data source=test;user id=test;password=test";
comm.CommandText = "SELECT * FROM test";
comm.Connection = conn;
conn.Open();
// Do something with the database
conn.Close();
conn.Dispose();
comm.Dispose();
dr.Close();

The code takes the necessary steps to return resources to the system, but the previous samples may be extended to take advantage of the try/catch syntax to make sure objects are disposed. The previous VB.NET sample is extended to use a try block to make sure object resources are released:

Dim conn As SqlConnection
Dim comm As SqlCommand
Dim dr As SqlDataReader
conn = New SqlConnection()
comm = New SqlCommand()
Try
conn.ConnectionString = "data source=test;user id=test;password=test"
comm.CommandText = "SELECT * FROM test"
comm.CommandType = CommandType.Text
comm.Connection = conn
conn.Open()
dr = comm.ExecuteReader()
' Work with database
Catch ex As SqlException
Console.Writeline("SQL Error")
Catch ex As Exception
Console.Writeline("Exception")
Finally
If Not (conn Is Nothing) Then
If (conn.State = ConnectionState.Open) Then
conn.Close()
End If
conn.Dispose()
End If
If Not (comm Is Nothing) Then
comm.Dispose()
End If
If Not (dr Is Nothing) Then
If Not (dr.IsClosed) Then
dr.Close()
End If
End If
End Try

The revamped listing places the code to perform object cleanup in the finally block to ensure that the code is executed no matter what happens in the try section. The finally block is always executed regardless of whether an exception is encountered. Additional code has been added to make sure the objects exist before calling the dispose method.

Create your own classes

You can look at the classes in the .NET Framework library to see how and when the dispose method is implemented because you'll want to utilize it in any custom classes you develop. The dispose method may be included in your class by utilizing the IDisposable interface in the class declaration. The following VB.NET sample shows this in practice:

Public Class MyClass Implements IDisposable

(The details of using a dispose method in your code are beyond the scope of this article, but keep it in mind when designing your own classes.)

Clean up after yourself

Recognizing the need to call and use the dispose method is essential to developing applications that perform properly. Problems may arise when it is avoided. This is especially true when working with external resources like files or database connections.

TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically sign up today!

About

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

0 comments

Editor's Picks