Using (Instrucción, Visual Basic)

Declara el principio de un bloque Using y, opcionalmente, adquiere los recursos del sistema que controla el bloque.

Sintaxis

Using { resourcelist | resourceexpression }
    [ statements ]
End Using

Partes

Término Definición
resourcelist Obligatorio si no se proporciona resourceexpression. Indica de uno o más recursos del sistema que controla este bloque Using, separados por comas.
resourceexpression Obligatorio si no se proporciona resourcelist. Variable o expresión de referencia que hace referencia a un recurso del sistema que este bloque Using va a controlar.
statements Opcional. Bloque de instrucciones que ejecuta el bloque Using.
End Using Necesario. Finaliza la definición del bloque Using y elimina todos los recursos que controla.

Cada recurso de la parte resourcelist tiene la sintaxis y las partes siguientes:

resourcename As New resourcetype [ ( [ arglist ] ) ]

O bien

resourcename As resourcetype = resourceexpression

Partes de resourcelist

Término Definición
resourcename Obligatorio. Variable de referencia que hace referencia a un recurso del sistema que el bloque Using controla.
New Obligatorio si la instrucción Using adquiere el recurso. Si ya ha adquirido el recurso, use la segunda alternativa de sintaxis.
resourcetype Necesario. Clase del recurso. La clase debe implementar la interfaz IDisposable.
arglist Opcional. Lista de argumentos que se pasan al constructor para crear una instancia de resourcetype. Consulte Lista de parámetros.
resourceexpression Necesario. Variable o expresión que hace referencia a un recurso del sistema que cumple los requisitos de resourcetype. Si usa la segunda alternativa de sintaxis, debe adquirir el recurso antes de pasar el control a la instrucción Using.

Comentarios

A veces, el código requiere un recurso no administrado, como un identificador de archivo, un contenedor COM o una conexión SQL. Un bloque Using garantiza la eliminación de uno o varios recursos cuando el código haya terminado con ellos. Esto hace que estén disponibles para que otro código los usen.

El recolector de elementos no utilizados (GC) de .NET Framework elimina los recursos administrados sin ninguna codificación adicional por su parte. No necesita un bloque Using para los recursos administrados. Sin embargo, todavía se puede utilizar un bloque Using para puede forzar la eliminación de un recurso administrado en lugar de esperar a que lo haga al recolector de elementos no utilizados.

Un bloque Using tiene tres partes: adquisición, uso y eliminación.

  • Adquisición significa crear una variable e inicializarla para hacer referencia al recurso del sistema. La instrucción Using puede adquirir uno o varios recursos, o bien puede adquirir exactamente un recurso antes de entrar en el bloque y suministrarlo a la instrucción Using. Si proporciona resourceexpression, debe adquirir el recurso antes de pasar el control a la instrucción Using.

  • Uso significa acceder a los recursos y realizar acciones con ellos. Las instrucciones entre Using y End Using representan el uso de los recursos.

  • Eliminación significa llamar al método Dispose en el objeto de resourcename. Esto permite que el objeto finalice limpiamente sus recursos. La instrucción End Using elimina los recursos bajo el control del bloque Using.

Comportamiento

Un bloque Using se comporta como una construcción Try...Finally en la que el bloque Try usa los recursos y el bloque Finally los elimina. Por este motivo, el bloque Using garantiza la eliminación de los recursos, independientemente de cómo salga del bloque. Esto es cierto incluso en el caso de una excepción no controlada, excepto para StackOverflowException.

El ámbito de cada variable de recurso adquirida por la instrucción Usingse limita al bloque Using.

Si especifica más de un recurso del sistema en la instrucción Using, el efecto es el mismo que si se anidan Using bloques uno dentro de otro.

Si resourcename es Nothing, no se realiza ninguna llamada a Dispose y no se produce ninguna excepción.

Control estructurado de excepciones dentro de un bloque de uso

Si necesita controlar una excepción que puede producirse dentro del bloque Using, puede agregarle una construcción completa Try...Finally. Si necesita controlar el caso en el que la instrucción Using no se ha realizado correctamente en la adquisición de un recurso, puede probar para ver si resourcename es Nothing.

Control estructurado de excepciones en lugar de un bloque de uso

Si necesita un control más preciso sobre la adquisición de los recursos o necesita código adicional en el bloque Finally, puede volver a escribir el bloque Using como una construcción Try...Finally. En el ejemplo siguiente se muestran las construcciones Try y Using de esqueleto equivalentes en la adquisición y eliminación de resource.

Using resource As New resourceType
    ' Insert code to work with resource.
End Using

' For the acquisition and disposal of resource, the following  
' Try construction is equivalent to the Using block.
Dim resource As New resourceType
Try
    ' Insert code to work with resource.
Finally
    If resource IsNot Nothing Then
        resource.Dispose()
    End If
End Try

Nota

El código dentro del bloque Using no debe asignar el objeto en resourcename a otra variable. Al salir del bloque Using, se elimina el recurso y la otra variable no puede acceder al recurso al que apunta.

Ejemplo

En el ejemplo siguiente se crea un archivo denominado log.txt y se escriben dos líneas de texto en el archivo. En el ejemplo también se lee ese mismo archivo y se muestran las líneas de texto:

Dado que las clases TextWriter y TextReader implementan la interfaz IDisposable, el código puede usar instrucciones Using para asegurarse de que el archivo se cierra correctamente después de las operaciones de escritura y lectura.

Private Sub WriteFile()
    Using writer As System.IO.TextWriter = System.IO.File.CreateText("log.txt")
        writer.WriteLine("This is line one.")
        writer.WriteLine("This is line two.")
    End Using
End Sub

Private Sub ReadFile()
    Using reader As System.IO.TextReader = System.IO.File.OpenText("log.txt")
        Dim line As String

        line = reader.ReadLine()
        Do Until line Is Nothing
            Console.WriteLine(line)
            line = reader.ReadLine()
        Loop
    End Using
End Sub

Vea también