Visualizzazione dei risultati da 1 a 4 su 4
  1. #1

    [VB2010] Errore CA2000 chiamare System.IDisposable.Dispose

    Questo codice:

    codice:
    'dimensiono FUORI dal Try/Catch per disporne nel blocco Finally
    'setto a nothing per non avere avviso di variabile con valore Null 
    Dim dt As DataTable = Nothing
    Dim DBconn As OleDbConnection = Nothing
    Dim da As OleDbDataAdapter = Nothing
    Dim ds As DataSet = Nothing
    Dim DBcommand As OleDbCommandBuilder = Nothing
    
    Try
    
         DBconn = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & Path)
         DBconn.Open()
    
         da = New OleDbDataAdapter("Select * From " & Tabella, DBconn)
    
         DBcommand = New OleDbCommandBuilder(da)
    
         ds = New DataSet
         da.FillSchema(ds, SchemaType.Source, Tabella)
         da.MissingSchemaAction = MissingSchemaAction.AddWithKey
         da.Fill(ds, Tabella)
         dt = New DataTable
         dt = ds.Tables(Tabella)
    
         Dim FoundRow As DataRow = Nothing
    
         '...............................................
         'ricerco e gestisco i dati
         '..............................................
    
    Catch ex As Exception
    
         Debug.Print("Error.: " & ex.ToString)
    
    Finally
    
          DBconn.Close()
          dt.Dispose()
          da.Dispose()
          ds.Dispose()
          DBcommand.Dispose()
    
    End Try
    funziona benissimo, senza errori. Però ho un avviso:

    CA2000 : Microsoft.Reliability : Nel metodo 'FrmMain.LeggeDB()' chiamare System.IDisposable.Dispose sull'oggetto 'dt' prima che tutti i relativi riferimenti siano esterni all'ambito.

    Eppure io ho ben messo dt.Dispose() nel blocco Finally, che viene letto COMUNQUE.

    Nota:
    - l' oggetto dt è l' unico che genera l' avviso
    - ho provato a cambiare l' ordine dei membri del blocco Finally ma non cambia nulla...

    Any idea?

  2. #2
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    prova ad eliminare questa linea:

    codice:
    dt = New DataTable

  3. #3
    Originariamente inviato da rsdpzed
    prova ad eliminare questa linea:

    codice:
    dt = New DataTable
    Era quella! Ma scusa, come mai mi dava avviso? Anche con quella riga dopotutto lo mettevo comunque a Dispose....

  4. #4
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    quando scrivi

    dt = New DataTable

    viene creato in memoria un oggetto DataTable vuoto. Nell'istruzione successiva, internamente, la funzione ds.Tables crea un altro oggetto DataTable e ne assegna il riferimento a dt.
    A questo punto in memoria ci sono due oggetti dataTable di cui uno 'appeso' e pronto per essere eliminato dal GC. Il problema è che gli oggetti IDisposible devono essere eliminati manualmente per diversi motivi tra cui il fatto che in alcuni casi non possono nemmeno essere eliminatidal GC.

    Comunque oggetti IDisposable o no, questo tipo di errore va sempre evitato anche se a dire il vero il JIT (che ha il compito di tradurre a runtime il codice MSIL in codice nativo) dovrebbe riconoscere l'inutilità di quella assegnazione ed eliminarla automaticamente senza nemmeno eseguirla.

    qualche altro tip:
    l'ordine dei dispose a volte (quindi per non sbagliare, sempre ) è importante, richiamali in ordine inverso rispetto alle assegnazioni.
    quando chiami dispose nei blocchi finally fai sempre cosi:

    codice:
    If TypeOf dt Is IDisposable Then
    	dt.Dispose()
    End If
    infatti nel tuo codice, se un eccezzione venisse sollevata in fase di apertura della connessione verrebbero chiamati dei dispose su oggetti che non sono stati ancora assegnati sollevando ulteriori eccezioni dal finally.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.