C # – Chiusura degli oggetti Sql best practice

Se hai una funzione C # con Sqlaccess, è obbligatorio chiudere tutti gli oggetti / maniglie, oppure tutto viene ripulito automaticamente una volta che si esce dalla funzione

Per esempio:

void DoSqlStuff() { SqlConnection sqlConn = new SqlConnection(...); SqlCommand cmd = new SqlCommand(...); SqlDataReader sqlData= null; sqlConn,Open(); sqlData = cmd.ExecutReader(); while(sqlData.Read()) { ... } } 

È opzionale, consigliato o obbligatorio chiudere SqlConn e SqlData?

Grazie.

Dovresti chiudere l’object SqlConnection non appena hai finito. Se non lo fai, la connessione rimarrà aperta e non sarà disponibile per gestire altre richieste.

L’istruzione using è utile per questo. Chiamerà Dispose () sull’object per te:

 using (SqlConnection cn = new SqlConnection(connectionString)) { SqlCommand cm = new SqlCommand(commandString, cn) cn.Open(); cm.ExecuteNonQuery(); } 

Non è necessario disporre di un’istruzione using separata per SqlDataReader (nonché di un’istruzione using per la connessione) a meno che non si pianifichi di eseguire altre operazioni con la connessione dopo che SqlDataReader ha letto completamente il set di righe.

Se stai semplicemente aprendo una connessione, leggendo alcuni dati usando il lettore, e quindi chiudendo la connessione, allora una sola istruzione per l’intero blocco di codice (che circonda la connessione) sarà sufficiente in quanto il garbage collector pulirà tutte le risorse legate al connessione che è eliminata dalla prima istruzione using.

Ad ogni modo, ecco un buon articolo che descrive tutto …

Dovresti chiudere tutto prima di tornare dalla funzione. Aprire datareader significa cursori aperti sul database, con conseguente aumento dell’utilizzo della memoria. Lo stesso vale per le connessioni al database.

Gli oggetti non utilizzati non vengono immediatamente liberati in C #, ma solo quando viene eseguita la garbage collection, che non è deterministica.

Tutte e tre le classi hanno un metodo Dispose (). Obbligatorio è troppo forte, ma sicuramente altamente raccomandato si utilizza la parola chiave using così Dispose () viene chiamato automaticamente. In caso contrario, il programma viene eseguito “pesante”, utilizzando più risorse di sistema del necessario. E fallimento assoluto quando non si utilizza la parola chiave “nuova” abbastanza per triggersre il garbage collector.

Chiamare Chiudi sulla connessione SQL in realtà non lo chiude, ma lo restituirà a un pool di connessioni per essere riutilizzato, migliorando le prestazioni.

Inoltre, è generalmente una ctriggers pratica non smaltire esplicitamente le risorse non gestite quando hai finito con loro (al più presto).

Stai attento con gli assoluti qui. Molto dipende da cosa stai facendo e da dove possono essere le inefficienze. In una pagina Web in cui ogni utente ha un contesto di sicurezza separato, potrebbe non esserci altra scelta che stabilire una nuova connessione SQL con nuove credenziali di sicurezza con ogni colpo di pagina. Chiaramente meglio se si può usare un pool di connessioni SQL con un contesto di sicurezza condiviso e lasciare che la pagina Web filtri i risultati, ma forse non è ansible.

Nelle prime versioni di SQL Server cioè (v6.5 o meno) l’autenticazione di accesso è stata eseguita da SQL Server. Inoltre, SQL era severamente limitato dalla memoria di connessione e dal numero di connessioni attive che poteva gestire. Quindi è stata una buona idea abbandonare la connessione quando non è in uso. Posta v6.5, la maggior parte delle persone usa l’autenticazione di Windows per accedere a SQL. Ciò causa molte chiamate di rete tra i server e un po ‘di latenza. Kerberos Security è ancora più loquace, quindi stabilire una connessione SQL è costoso. Per questo motivo è necessario trovare un equilibrio tra Mantenimento di una connessione aperta per la durata della propria applicazione WinForms vs Apertura e chiusura all’interno di ciascuna chiamata di metodo.

Come una guida approssimativa, se pensi che la tua app vorrà parlare con SQL nel prossimo, diciamo 30 secondi. Mantieni aperta la connessione stabilita. Se hanno ridotto al minimo la tua app, non l’hanno toccata entro un periodo di timeout, o hai tutti i dati nella RAM e difficilmente avranno bisogno di qualcosa di più dal sistema SQL. Chiudi la connessione.

Valutare la possibilità di creare una class con un timer di sistema per mantenere la connessione. La class fornirà sempre una connessione valida, ma forse la class sceglierà di rilasciarla e liberare il carico di connessione su SQL, quando appropriato.

A meno che non si stia scrivendo anche codice basato su server, una piccola quantità di inefficienza della memoria potrebbe non essere notata. Ma 2-10.000 clienti che utilizzano male i tuoi server di sicurezza e dati probabilmente mettono in ginocchio il tuo Data Center.

L’eliminazione esplicita nella dichiarazione finale è un altro approccio, sebbene l’istruzione using sia una soluzione molto migliore. Produce un po ‘più di codice, ma dimostra l’objective …

 SqlConnection conn = null; try { //create connection SqlCommand cmd = null; try { //create command SqlDataReader reader = null; try { //create reader } finally { reader.Dispose(); } } finally { cmd.Dispose(); } } finally { conn.Dispose(); } 

Qualsiasi class che gestisca elementi SQL come Connections dovrebbe implementare l’interfaccia IDisposable come stabilito dalle linee guida di codifica di Microsoft .NET.

Pertanto, dovresti probabilmente chiudere e disporre la tua connessione nel metodo Dispose.