martes, 20 de noviembre de 2007

Usando Using e IDisposable

Cuando empecé el curso de mi primera certificación Microsoft, que estoy justo por la mitad de temario y tiempo, nuestro tutor nos pidió que investigáramos los métodos para eliminar objetos que ya hemos utilizado de la memoria. El típico Dispose u object = nothing.

Pasaron las semanas y me encontré un día estudiando las diversas formas de pegarte con un SQLDataAdapter y entré a una página de MSDN en donde utilizaban una extraña instrucción que no había visto nunca: Using.

Using connection As New OleDbConnection(connectionString)

Dim command As New OleDbCommand(queryString, connection)
command.CommandTimeout = 20
connection.Open()

Dim reader As OleDbDataReader = command.ExecuteReader()
While reader.Read()
Console.WriteLine(reader(0).ToString())
End While reader.Close()
End Using

Visto el cómo se utilizaba y lo que hacía, fui raudo y veloz a comentárselo a mis tutores los cuales me confirmaron que es una instrucción de .NET 2.0 que nos reduce mucho el código y evita puntos de error por olvidar cerrar una conexión o liberar el adaptador.

Mira en el ejemplo lo que varía el código usando Using y sin usarlo.

Tan contento, voy y defino una clase de conexión a la base de datos, con las llamadas a los procedimientos almacenados y demás zaranjandas, para ser invocado desde la capa de negocio de la aplicación. Pero me llevo la sorpresa que, cuando voy a utilizar Using, me dice que mi clase debe tener implementado el método IDisposable.

En el primer momento me vi recorriendo MSDN, la web del Guille y demás foros buscando a qué se refería, más entonces recordé que en la Certificación hemos dado Interfaces… ¡¡y con eso he amortizado el curso entero!!

Ni corto ni perezoso me voy a mi clase de conexión y le digo:

Implements IDisposable

Ale hooop!!, por arte de Magia (de Visual Studio) se me añaden los parámetros y métodos que necesito para que mi clase soporte Idisposable y que pueda utilizar Using.

Taxativamente te avisa que no lo toques… ;D

Private disposedValue As Boolean = False ' To detect redundant calls

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free managed resources when explicitly called
End If

' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub

#Region " IDisposable Support "
This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region

Y ahora estoy SEGURO que no voy a intentar abrir una conexión que ya está abierta, ni catorce conectores en memoria… :D

1 comentario:

Anónimo dijo...

Interesante. Oye, ¿y qué pasa si ocurre una excepción en un bloque Using? ¿Se pueden anidar Usings?

Julio.