none
Corretto utilizzo di Using..End Using RRS feed

  • Domanda

  • Ciao e grazie a tutti per le stupende risposte!

    Adesso ho capito la differenza!

    Vi pongo un ultimo quesito, che spesso ho incontrato e  mai appreso bene..

    Come si sfruttano gli using <...> end using in modo corretto?

    Sopratutto, quando si arriva all'end using viene chiamata la iDisposable in automatico?

    Tale iDisposable se ho ben capito serve a rilasciare le risorse non più necessarie, come ad esempio oggetti instanziati.. però non mi è chiaro come essa vada scritta...

    Per tornare ad argomenti pratici, mettiamo questo esempio che uso per leggere un file di testo.

    Imports System.IO
    
    Public Class Lettura
      Public Function Leggi(ByVal Path As String) As String
        Dim sr As StreamReader = New StreamReader(Path)
        Return sr.ReadToEnd
      End Function
    End Class
    
    

    Come potrei implementare l'iDisposable? e come poi conviene usare gli using end using in maniera corretta nella form che instanzia ed usa tale classe?

     

    Grazie davvero a tutti!

    mercoledì 27 ottobre 2010 13:01

Risposte

  • Il blocco Using ... End Using aiuta il programmatore nell'utilizzare correttamente tutte le classi che implementano IDisposable. Tipicamente se una classe implementa IDisposable significa che è necessario richiamarne il metodo Dispose perchè alcune azioni importanti (ad esempio il rilascio di risorse, la chiusura di files, connessioni, ecc...) viene esplicitamente effettuata dal codice scritto all'interno di questo metodo. Il metodo Dispose è inoltre richiamato automaticamente quando il Garbage Collector distrugge la classe (spero tu sappia come viene gestito il GC nel framework...), quindi prima o poi qualcuno quel codice lo richiamerà. Se tu lasci che il compito venga gestito dal GC può verificarsi qualche problema, perchè non sai esattamente quando la tua classe verrà distrutta poichè, essendo il GC un processo gestito dal SO, tu non ne hai il controllo diretto (a meno che non lo gestisci da codice attraverso il meccanismo offerto dall'intertfaccia IDispose). In due parole Using ... End Using ti risolve il problema. Analizziamo questi due frammenti di codice:

     Public Function Leggi(ByVal Path As String) As String
      Dim sr As StreamReader = New StreamReader(Path)
      Return sr.ReadToEnd
     End Function
    
     Public Function Leggi(ByVal Path As String) As String
      Dim RetValue as String
      Using sr As New StreamReader (Path)
        RetValue = sr.ReadToEnd
      End Using
      Return RetValue
     End Function
    

    ll primo frammento apre uno stream reader, legge una variabile e la ritorna come valore (addirittura per riferimento!!!!). Non leggo nessun codice che chiuda il file letto che ovviamente rimane aperto finchè l'oggetto sr non viene distrutto (ATTENZIONE!!!! Uscire dall'area di validità NON significa distruggere la classe StreamReader).

    Nel secondo frammento invece utilizzi uno stream reader all'interno di un blocco Using ... End Using, questo significa che il metodo Dispose dell'oggetto sr viene richiamato automaticamente dall'End Using, si presume che il metodo Dispose abbia al suo interno (e così è) il codice che chiude il file aperto facendoti dormire sonni tranquilli.

    In linea di massima ogni volta che usi una classe che implementa l'interfaccia IDisposable sarebbe corretto richiamarne il metodo Dispose oppure utilizzarla all'interno di un blocco Using ... End Using.

    Un'ulteriore raccomandazione è quella di evitare di richiamare esplicitamente i metodi del GC poichè molto dispendiosi da un punto di vista di allocazione di risorse.

    HTH

     


    Alberto De Luca [MVP - Visual Basic .NET]
    mercoledì 27 ottobre 2010 17:01
  • Non tutte le tue classi hanno la necessità di implementare la IDisposable.
    In generale una tua classe è opportuno implementi la IDisposable quando uno dei suoi attributi implementa IDisposable e, quindi, hai la necessità di avere un punto in cui richiamare su di esso Dispose, oppure se uno dei suoi attributi è il riferimento ad un oggetto unmanaged (ad esempio un riferimento ad un oggetto COM) o se hai grosse quantità di dati da rilasciare.
    In tutti gli alti casi non hai la necessità di implementare IDisposable.

    giovedì 28 ottobre 2010 09:22
    Moderatore
  • Se può interessarti, per capire la gestione del ciclo di vita di un oggetto .NET e come/quando implementare IDisposable, ti puoi scaricare gratuitamente il capitolo 8 del mio libro "VB 2010 Unleashed" dal titolo "Managing an object's lifetime". Lo trovi qui:

    http://msdn.microsoft.com/en-us/vbasic/bb897562.aspx


    Alessandro Del Sole
    Microsoft MVP - Visual Basic: development
    http://community.visual-basic.it/alessandro/
    sabato 30 ottobre 2010 14:19

Tutte le risposte

  • Il blocco Using ... End Using aiuta il programmatore nell'utilizzare correttamente tutte le classi che implementano IDisposable. Tipicamente se una classe implementa IDisposable significa che è necessario richiamarne il metodo Dispose perchè alcune azioni importanti (ad esempio il rilascio di risorse, la chiusura di files, connessioni, ecc...) viene esplicitamente effettuata dal codice scritto all'interno di questo metodo. Il metodo Dispose è inoltre richiamato automaticamente quando il Garbage Collector distrugge la classe (spero tu sappia come viene gestito il GC nel framework...), quindi prima o poi qualcuno quel codice lo richiamerà. Se tu lasci che il compito venga gestito dal GC può verificarsi qualche problema, perchè non sai esattamente quando la tua classe verrà distrutta poichè, essendo il GC un processo gestito dal SO, tu non ne hai il controllo diretto (a meno che non lo gestisci da codice attraverso il meccanismo offerto dall'intertfaccia IDispose). In due parole Using ... End Using ti risolve il problema. Analizziamo questi due frammenti di codice:

     Public Function Leggi(ByVal Path As String) As String
      Dim sr As StreamReader = New StreamReader(Path)
      Return sr.ReadToEnd
     End Function
    
     Public Function Leggi(ByVal Path As String) As String
      Dim RetValue as String
      Using sr As New StreamReader (Path)
        RetValue = sr.ReadToEnd
      End Using
      Return RetValue
     End Function
    

    ll primo frammento apre uno stream reader, legge una variabile e la ritorna come valore (addirittura per riferimento!!!!). Non leggo nessun codice che chiuda il file letto che ovviamente rimane aperto finchè l'oggetto sr non viene distrutto (ATTENZIONE!!!! Uscire dall'area di validità NON significa distruggere la classe StreamReader).

    Nel secondo frammento invece utilizzi uno stream reader all'interno di un blocco Using ... End Using, questo significa che il metodo Dispose dell'oggetto sr viene richiamato automaticamente dall'End Using, si presume che il metodo Dispose abbia al suo interno (e così è) il codice che chiude il file aperto facendoti dormire sonni tranquilli.

    In linea di massima ogni volta che usi una classe che implementa l'interfaccia IDisposable sarebbe corretto richiamarne il metodo Dispose oppure utilizzarla all'interno di un blocco Using ... End Using.

    Un'ulteriore raccomandazione è quella di evitare di richiamare esplicitamente i metodi del GC poichè molto dispendiosi da un punto di vista di allocazione di risorse.

    HTH

     


    Alberto De Luca [MVP - Visual Basic .NET]
    mercoledì 27 ottobre 2010 17:01
  • Non tutte le tue classi hanno la necessità di implementare la IDisposable.
    In generale una tua classe è opportuno implementi la IDisposable quando uno dei suoi attributi implementa IDisposable e, quindi, hai la necessità di avere un punto in cui richiamare su di esso Dispose, oppure se uno dei suoi attributi è il riferimento ad un oggetto unmanaged (ad esempio un riferimento ad un oggetto COM) o se hai grosse quantità di dati da rilasciare.
    In tutti gli alti casi non hai la necessità di implementare IDisposable.

    giovedì 28 ottobre 2010 09:22
    Moderatore
  • Se può interessarti, per capire la gestione del ciclo di vita di un oggetto .NET e come/quando implementare IDisposable, ti puoi scaricare gratuitamente il capitolo 8 del mio libro "VB 2010 Unleashed" dal titolo "Managing an object's lifetime". Lo trovi qui:

    http://msdn.microsoft.com/en-us/vbasic/bb897562.aspx


    Alessandro Del Sole
    Microsoft MVP - Visual Basic: development
    http://community.visual-basic.it/alessandro/
    sabato 30 ottobre 2010 14:19