2009-07-21 11 views
5

Ho il codice qui sotto per interrogare i record da una procedura memorizzata, ma sono preoccupato che non possa smaltire ciò di cui ho bisogno o mi stia smaltendo quando l'oggetto verrà eliminato dal Garbage Collector poco dopo comunque.C# sql cosa smaltire

Devo disporre di SqlDataReader poiché si trova nel blocco di prova try?

Devo eseguire entrambi cmd.Dispose e cmd.Connection.Close o si deduce l'altro?

Il garbage collector eliminerà comunque tutti questi oggetti (forse non abbastanza tempestivamente) o questi oggetti implicitamente richiedono di essere eliminati probabilmente a causa dell'uso di codice non gestito?

public void GetData(string studentID) 
    { 
     SqlCommand cmd = new SqlCommand("sp_stored_proc", 
       new SqlConnection(Settings.Default.connectionString)) 
       { CommandType = CommandType.StoredProcedure }; 
     try 
     { 
      cmd.Connection.Open(); 
      cmd.Parameters.AddWithValue("@student_id", studentID); 
      SqlDataReader dr = cmd.ExecuteReader(); 

     //do something with the data 

      if (dr != null) 
       dr.Dispose(); 
     } 
     catch 
     { 
      //error handling 
     } 
     finally 
     { 
      if (cmd != null) 
      { 
       cmd.Dispose(); 
       cmd.Connection.Close(); 
      } 

     } 

    } 

risposta

16

È necessario disporre il lettore di dati e il comando. Non è necessario chiudere separatamente la connessione se si dispone del comando. Si dovrebbe idealmente fare entrambe le cose utilizzando un blocco using:

using (SqlCommand cmd = new...) 
{ 
    // do stuff 
    using (SqlDataReader dr = cmd.ExecuteReader()) 
    { 
     // do stuff 
    } 
} 

Se avete bisogno di fare la gestione delle eccezioni che separatamente all'interno o intorno ai blocchi utilizzando - non c'è bisogno per la fine per le chiamate Dispose però con using.

+1

Se potessi revocare questo più di una volta, lo farei. VIENI A PERSONE! UTILIZZI CON I BLOCCHI! –

+2

Smaltire l'oggetto 'SqlCommand' ** non ** dispose il' SqlConnection'. Questo è molto facile da testare. http://stackoverflow.com/questions/60919/is-sqlcommand-dispose-enough/60934#60934 – arcain

+0

Devo gettare il lettore anche se dispongo il comando? Devo disporre il comando anche se dispongo la connessione? Puoi riferirci a qualsiasi fonte di questo? – Lii

3

Devo smaltire la SqlDataReader dal momento che è all'interno del try cattura blocco?

- Sì, poiché all'interno del fermo di prova non viene chiamato il metodo di smaltimento.

Devo eseguire entrambi cmd.Dispose e cmd.Connection.Close o si deduce l'altro?

- Sì, è necessario eseguire entrambi. Chiamare Cmd.dispose non chiude la connessione.

Il metodo dispose è pensato per essere utilizzato dal programmatore per ripulire le risorse che non sono gestite direttamente dal garbage collector, o la necessità di essere cancellate dopo che il programma è stato fatto usandole per liberare spazio. Tecnicamente, si potrebbe configurare il programma in modo che il GC gestisca la sua eliminazione, ma questa è un'ipotesi che non creerei, specialmente dal momento che il programmatore che ha scritto la classe ha esposto il metodo di smaltimento per te. Inserire il comando in un'istruzione using è probabilmente il percorso più semplice, perché sai che verrà eliminato quando il codice lascia lo spazio della dichiarazione.

using (var connection = new Connection()) 
{ 
    using (var cmd = new Command()) 
    { 



    } 
} 
+0

"no, cmd.dispose chiuderà la connessione" - Penso che non sia corretto; per quanto ne so, chiamare Dispose sul comando non ha nulla a che fare con la sua connessione. –

+0

@Kevin: il post che hai collegato dichiara che chiamare Dispose su un oggetto * connessione * chiamerà close su quello stesso oggetto. La parola "comando" non appare sulla pagina. –

+0

Ho letto male il post quando ho ricontrollato. Hai ragione. – kemiller2002

2

Personalmente, se qualcosa ha un metodo di smaltimento, vale la pena utilizzarlo in ogni caso in quanto impediscono perdite di memoria protettive.

3

Se si utilizza qualcosa di simile:

public void GetData(string studentID) 
{ 
    using (SqlConnection connection = new SqlConnection(Settings.Default.connectionString)) 
    { 
     connection.Open(); 

     using (SqlCommand command = connection.CreateCommand()) 
     { 
      command.CommandType = CommandType.StoredProcedure; 
      command.CommandText = "sp_stored_proc"; 
      command.Parameters.AddWithValue("@student_id", studentID); 

      using (SqlDataReader dataReader = command.ExecuteReader()) 
      { 
       // do something with the data 
      } 
     } 
    } 
} 

poi tutti gli oggetti usa e getta andranno smaltiti correttamente. Chiamando Dispose() sugli oggetti SqlConnection, SqlCommand e SqlDataReader (che è ciò che fa il blocco using quando esce) li chiude correttamente.

Inoltre, questo approccio mantiene tutte le variabili nell'ambito del punto in cui vengono utilizzate.

Lo svantaggio di questo approccio è che se hai bisogno di una gestione degli errori usando un try/catch, devi avvolgerlo attorno all'intero corpo del metodo, o usarne diversi per gestire gli errori di connessione in modo diverso dagli errori di lettura, ecc. ..

1

Per farla breve; se implementa IDisposable, è necessario chiamare Dispose.

Anche se si utilizza Reflector per capire che Dispose in un oggetto invoca Dispose su un altro oggetto, io consiglierei comunque di chiamare Dispose su entrambi, dal momento che questo è dettagli interni di implementazione che possono cambiare in qualche versione futura, in modo non dovresti fare affidamento sul fatto che sia sempre vero.

Quindi, Dispose qualsiasi cosa che sia IDisposable.

-4

è necessario aprire Connessione prima tramite Connection.Open(); quindi utilizzare i metodi come SqlDataReader per leggere dopo tutto, chiudere SqlDataReader in primo luogo e poi stretta connessione

è possibile utilizzare parole chiave "utilizzando" di disporre di esso, ma non è una buona idea

infatti la la parola chiave "usare" è disporre l'oggetto automaticamente. in altre parole, l'oggetto dovrebbe raggiungere il metodo di smaltimento

+0

-1 stai dicendo che usare i blocchi è una cattiva idea? –

+0

Si prega di approfondire il motivo per cui l'uso del costrutto è una cattiva idea in questo caso. – LOAS