2010-04-25 10 views
15

Supponiamo che io ho il seguente codice:L'istruzione using C# esegue try/finally?

private void UpdateDB(QuoteDataSet dataSet, Strint tableName) 
{ 
    using(SQLiteConnection conn = new SQLiteConnection(_connectionString)) 
    { 
     conn.Open(); 
     using (SQLiteTransaction transaction = conn.BeginTransaction()) 
     { 
      using (SQLiteCommand cmd = new SQLiteCommand("SELECT * FROM " + tableName, conn)) 
      { 
       using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter()) 
       { 
        sqliteAdapter.Update(dataSet, tableName); 
       } 
      } 
      transaction.Commit(); 
     } 
    } 
} 

Il C# documentazione afferma che con una dichiarazione using l'oggetto all'interno del campo di applicazione sarà smaltito e ho visto molti posti dove è suggerito che non abbiamo bisogno di usare la clausola try/finally.

Di solito mi circondano le connessioni con un try/finally, e chiudo sempre la connessione nella clausola finally. Dato il codice di cui sopra, è ragionevole presumere che la connessione verrà chiusa se c'è un'eccezione?

+0

Simile a http://stackoverflow.com/questions/278902/ using-statement-vs-try-finally –

+5

Non è una risposta alla tua domanda. Si prega di leggere sugli attacchi sql injection. –

risposta

18

You are correct; the using statement compiles to a try/finally block.

Il compilatore trasforma using(resource) statement; nel codice seguente:.

{ 
    ResourceType resource = expression; 
    try { 
     statement; 
    } 
    finally { 
     if (resource != null) ((IDisposable)resource).Dispose(); 
    } 
} 

(Il cast di IDisposable è nel caso in cui ResourceType attrezzi IDisposable esplicitamente

+0

cosa è meglio rilasciare una risorsa che non può essere istanziata all'interno di un'istruzione o di essere riutilizzata o passata come parametro? – bjan

+0

@bjan: dipende dalla situazione. – SLaks

1

Si può presumere che la connessione verrà chiusa se si ottiene un'eccezione.

10

Sì, è necessario utilizzare un'istruzione try/finally o using. Non hai bisogno di entrambi.

A using statement è quasi lo stesso di try/finally tranne che in C# 3 non è possibile riassegnare la variabile all'interno del blocco using.

using (IDisposable d = foo()) 
{ 
    d = null; // Error: Cannot assign to 'd' because it is a 'using variable' 
} 

In precedenza si poteva riassegnare ma l'oggetto originale sarebbe ancora da smaltire, non l'oggetto appena assegnato e si dovrebbe anche ottenere questo compilazione di avvertimento:

assegnazione Possibilmente scorretto locale 'd', che è l'argomento di un'istruzione using o lock. La chiamata Dispose o lo sblocco avverranno sul valore originale del locale.

+0

cosa è meglio rilasciare una risorsa che non può essere istanziata all'interno di un'istruzione o riutilizzata o passata come parametro? – bjan

6

Sì, la dichiarazione using è praticamente solo una scorciatoia per un blocco try ... finally.

Ad esempio, questo codice ...

using (MyDisposableType foo = new MyDisposableType()) 
{ 
    foo.DoSomething(); 
} 

... sarebbe pari al seguente ...

{ 
    MyDisposableType foo = new MyDisposableType(); 
    try 
    { 
     foo.DoSomething(); 
    } 
    finally 
    { 
     if (foo != null) 
      ((IDisposable)foo).Dispose(); 
    } 
} 
1

Utilizzando() assicura che l'elemento istanziata all'interno dei parametri sarà smaltito indipendentemente da ciò che accade all'interno del blocco di codice associato. Ciò include la chiusura della connessione al database presupponendo che SQLiteConnection gestisca correttamente la sua eliminazione.