Istruzione Using (Visual Basic)

Dichiara l'inizio di un blocco Using e, facoltativamente, acquisisce le risorse di sistema che il blocco controlla.

Sintassi

Using { resourcelist | resourceexpression }
    [ statements ]
End Using

Parti

Termine Definizione
resourcelist Obbligatorio se non si specifica resourceexpression. Elenco di una o più risorse di sistema che questo blocca Using controlla, separate da virgole.
resourceexpression Obbligatorio se non si specifica resourcelist. Variabile o espressione di riferimento che fa riferimento a una risorsa di sistema da controllare da questo blocco Using.
statements Facoltativo. Blocco di istruzioni eseguite dal blocco Using.
End Using Obbligatorio. Termina la definizione del blocco Using ed elimina tutte le risorse che controlla.

Ogni risorsa nella parte resourcelist presenta la sintassi e le parti seguenti:

resourcename As New resourcetype [ ( [ arglist ] ) ]

oppure

resourcename As resourcetype = resourceexpression

Parti dell'elenco di risorse

Termine Definizione
resourcename Obbligatorio. Variabile di riferimento che fa riferimento a una risorsa di sistema che il blocco Using controlla.
New Obbligatorio se l'istruzione Using acquisisce la risorsa. Se la risorsa è già stata acquisita, usare la seconda alternativa di sintassi.
resourcetype Obbligatorio. Classe della risorsa. La classe deve anche implementare l'interfaccia IDisposable.
arglist Facoltativo. Elenco di argomenti passati al costruttore per creare un'istanza di resourcetype. Vedere Elenco parametri.
resourceexpression Obbligatorio. Variabile o espressione che fa riferimento a una risorsa di sistema che soddisfa i requisiti di resourcetype. Se si usa la seconda alternativa di sintassi, è necessario acquisire la risorsa prima di passare il controllo all'istruzione Using.

Osservazioni:

A volte il codice richiede una risorsa non gestita, ad esempio un handle di file, un wrapper COM o una connessione SQL. Un blocco Using garantisce l'eliminazione di una o più risorse di questo tipo al termine del codice. In questo modo è possibile renderli disponibili per l'uso da parte di altro codice.

Le risorse gestite vengono eliminate dal Garbage Collector (GC) di .NET Framework senza scrivere codice aggiuntivo. Non è necessario un blocco di Using per le risorse gestite. Tuttavia, è comunque possibile usare un blocco Using per forzare l'eliminazione di una risorsa gestita anziché attendere il Garbage Collector.

Un blocco di Using ha tre parti: acquisizione, utilizzo ed eliminazione.

  • Acquisizione significa creare una variabile e inizializzarla per fare riferimento alla risorsa di sistema. L'istruzione Using può acquisire una o più risorse oppure è possibile acquisire esattamente una risorsa prima di immettere il blocco e fornirla all'istruzione Using. Se si specifica resourceexpression, è necessario acquisire la risorsa prima di passare il controllo all'istruzione Using.

  • Utilizzo significa accedere alle risorse ed eseguire azioni con esse. Le istruzioni tra Using e End Using rappresentano l'utilizzo delle risorse.

  • Smaltimento significa chiamare il metodo Dispose sull'oggetto in resourcename. In questo modo l'oggetto può terminare le risorse in modo pulito. L'istruzione End Using elimina le risorse sotto il controllo del blocco Using.

Comportamento

Un blocco Using si comporta come una costruzione Try...Finally in cui il blocco Try utilizza le risorse e il blocco Finally li elimina. Per questo motivo, il blocco Using garantisce l'eliminazione delle risorse, indipendentemente dal modo in cui si esce dal blocco. Questo vale anche nel caso di un'eccezione non gestita, ad eccezione di StackOverflowException.

L'ambito di ogni variabile di risorsa acquisita dall'istruzione Using è limitato al blocco Using.

Se si specificano più risorse di sistema nell'istruzione Using, l'effetto è uguale a quello dei blocchi Using annidati uno all'interno dell'altro.

Se resourcename è Nothing, non viene eseguita alcuna chiamata a Dispose e non viene generata alcuna eccezione.

Gestione strutturata delle eccezioni all'interno di un blocco using

Se è necessario gestire un'eccezione che potrebbe verificarsi all'interno del blocco Using, è possibile aggiungere una costruzione Try...Finally completa. Se è necessario gestire il caso in cui l'istruzione Using non riesce ad acquisire una risorsa, è possibile verificare se resourcename è Nothing.

Gestione delle eccezioni strutturate anziché un blocco using

Se è necessario un controllo più corretto sull'acquisizione delle risorse o è necessario codice aggiuntivo nel blocco Finally, è possibile riscrivere il blocco di Using come costruzione Try...Finally. Nell'esempio seguente vengono illustrate costruzioni scheletriche Try e Using equivalenti nell'acquisizione e nell'eliminazione di 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

Il codice all'interno del blocco Using non deve assegnare l'oggetto in resourcename a un'altra variabile. Quando si esce dal blocco Using, la risorsa viene eliminata e l'altra variabile non può accedere alla risorsa a cui punta.

Esempio

L'esempio seguente crea un file denominato log.txt e scrive due righe di testo nel file. L'esempio legge anche lo stesso file e visualizza le righe di testo:

Poiché le classi TextWriter e TextReader implementano l'interfaccia IDisposable, il codice può usare istruzioni Using per assicurarsi che il file venga chiuso correttamente dopo le operazioni di scrittura e lettura.

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

Vedi anche