2012-03-08 7 views
10

Questa domanda è più di una qual è il modo giusto per fare qualcosa ...usa & try/catch nidificazione

La domanda ... c'è un adeguato ordine di nidificazione tra un blocco using e try/catch?

È possibile nidificare l'intera istruzione using all'interno di un try/catch e mantenere i vantaggi di un blocco using? (o un'eccezione farà sì che la parte finale dell'istruzione using venga espulsa dalla finestra)

Oppure dovresti annidare lo try/catch all'interno delle dichiarazioni using e circondare solo le istruzioni che consentono l'accesso al database?

Is ...

try { 
    using(tsmtcowebEntities db = new tsmtcowebEntities()) { 
      violationList = (from a in db.DriverTrafficViolationDetails 
          where a.DriverTrafficViolation.DriverApplicationId == DriverAppId 
          orderby a.DateOfOccurance descending 
          select a).ToList<DriverTrafficViolationDetail>(); 
      GeneralViolation = (from a in db.DriverTrafficViolations 
           where a.DriverApplicationId == DriverAppId 
           select a).FirstOrDefault(); 
    } 
} catch { } 

meno/più corretto di ...

using(tsmtcowebEntities db = new tsmtcowebEntities()) { 
    try { 
      violationList = (from a in db.DriverTrafficViolationDetails 
          where a.DriverTrafficViolation.DriverApplicationId == DriverAppId 
          orderby a.DateOfOccurance descending 
          select a).ToList<DriverTrafficViolationDetail>(); 
      GeneralViolation = (from a in db.DriverTrafficViolations 
           where a.DriverApplicationId == DriverAppId 
           select a).FirstOrDefault(); 
    } catch { } 
} 
+0

Avete davvero bisogno di tutti i dettagli della vostra applicazione nel codice fornito? Penso che un semplice esempio inventato sarebbe sufficiente. –

+1

Il blocco catch vuoto è una pratica di programmazione estremamente negativa. Non farlo! Te ne pentirai dopo. – phoog

+0

@JonathonReinhart Per me è stato più semplice copiare e incollare un blocco di codice piuttosto che creare un esempio. Ricicla il codice quando sento che mettere il codice là fuori per il mondo potrebbe essere cattivo. In questo caso non vedo negativi quindi perché no? – Jared

risposta

5

Il successivo è migliore: eviterà eccezioni di mascheratura eventualmente lanciate dy dispose. Vedere questo article.

+1

+1 per indicare questo: tuttavia, qualsiasi Dispose che genera un'eccezione è già "cattiva" nel mio libro :( –

+0

A meno che non si voglia rilevare gli errori generati dall'istruzione using. Qualcosa come usare (FileStream fs = new FileStream (... può essere lanciato facilmente se il percorso non è valido o inaccessibile e potrebbe anche essere più probabile che gettare rispetto al contenuto del blocco in uso. –

0

Vorrei suggerire mettendo il try/catch all'interno del usando perché a prescindere dal fatto che un'eccezione è buttare si dovrebbe smaltire i tipi il contenitore dell'entità Disposable

+0

Immagino che fosse parte della mia domanda. Sono stato al 100% positivo nella funzionalità di annidare il try/catch all'interno dell'utilizzo. Ero più incerto se un'istruzione using potesse gestire l'inverso e comunque disporre dell'oggetto/delle risorse ... Ho del codice su cui sto lavorando ed è attualmente in entrambi i casi. Sto cercando di scoprire se ho bisogno di leggere il codice e assicurarmi che il try/catch sia sempre nidificato o meno. Hai confermato ciò che inizialmente mi aspettavo, quindi accetterò la risposta! @GlennFerrieLive – Jared

+0

'using' esegue il proprio tentativo di cattura. La funzione 'Dispose' sarà sempre chiamata. –

+1

-1 Il deposito verrà chiamato indipendentemente dal nidificazione. @ Jared: l'uso è compilato in un try-finally (non try-catch come diceva J.N.). Dispose viene chiamato nel blocco finally, quindi viene chiamato anche se l'eccezione viene catturata o gestita. – phoog

2

È davvero una questione di stile e quanto ristretta si vuole mantenere l'ambito di db:

Se l'utilizzo è all'interno del blocco try/catch, la variabile db sarà accessibile solo nella porzione try.

Se l'utilizzo è esterno al blocco try/catch, sarà visibile all'interno della parte catch.

Indipendentemente da ciò, la variabile verrà eliminata correttamente perché il blocco using equivale a try/finally.

Personalmente mi chiederei perché è necessario rilevare eccezioni in assoluto e cosa, se non altro, si è in grado di fare con loro.

+0

Uso spesso try/catch per impostare un codice di stato per la risposta sulle mie azioni che vengono chiamate tramite ajax. – Jared

1

using nidi prevedibilmente con try/catch e Dispose saranno chiamati tutti su sentieri. Si intende che il controllo è sempre flussi da interni -> ambiti esterni (sia per Eccezioni che per il ritorno normale del flusso).

La domanda è allora: quando qualora il cattura essere eseguito in relazione al Dispose e cosa qualora il campo di applicazione della cattura essere? La risposta a questo può variare a seconda del codice ma deve essere ovviamente "all'interno" se è richiesto l'accesso a db e "all'esterno" se il codice è eseguito comeusing * potrebbe essere l'origine dell'eccezione.

(Inoltre, blocchi catch vuoti sono icky! Io parto dal presupposto che ci sono "a scopo dimostrativo".)

Felice di codifica.


* Si noti che un esterno catture interferirà eccezioni generate da new tsmtcowebEntities() o (come sottolineato da J.N.) il Dispose, dovrebbe qualsiasi esistere. (È un altro argomento interamente se è accettabile che entrambi i costrutti generino un'eccezione ;-) Preferisco catturare le eccezioni il più vicino possibile alla sorgente e lasciare che le eccezioni non sappiano come gestire "bleed out" escluso in determinati costrutti di livello superiore (ad es. Gestori di eventi).

+0

In realtà ho alcuni punti nel mio codice semplicemente perché ho Elmah impostato per catturare qualsiasi Eccezione Nella mia lista delle cose da fare è di tornare indietro e rifare un sacco di codice e i miei blocchi try/catch sono una di quelle aree, oltre a migliorare la configurazione della registrazione degli errori che ho. – Jared