2016-02-02 20 views
5

Sto cercando di capovolgerlo. Secondo this page su Using dichiarazioni:Come l'istruzione di uso di C# si traduce in Try-Finally

L'istruzione using assicura che Dispose viene chiamato anche se un'eccezione si verifica mentre si sta chiamando metodi sull'oggetto. È possibile ottenere lo stesso risultato inserendo l'oggetto in un blocco try e quindi chiamando Dispose in un blocco finally; in effetti, questo è il modo in cui l'istruzione using viene tradotta dal compilatore.

Ma this page circa Try-Finally blocchi si afferma:

All'interno un'eccezione gestita, il blocco associato, infine, è garantita da eseguire. Tuttavia, se l'eccezione non è gestita, l'esecuzione del blocco finally dipende da come viene attivata l'operazione di unwind dell'eccezione.

così come può una dichiarazione Using essere garantiti per chiamare il metodo Dispose in caso di un'eccezione se si traduce in un Try-Finally che non è garantito per chiamare il finally?

+0

Non una risposta perché non so che ho ragione, ma credo che stia dicendo che se c'è un'eccezione non gestita all'interno dell'affermazione, alla fine non verrà chiamata. Ma con la dichiarazione di cattura che viene autocreata usando, non c'è nient'altro che una chiamata a dispose(). – GendoIkari

+0

@GendoIkari: No, non è correlato al punto da cui viene lanciata l'eccezione, ma se è eventualmente catturato o meno. Un'eccezione alla fine catturata (gestita) invocherà il blocco finally, sempre (anche se un'altra eccezione è generata da un fermo). Un'eccezione non gestita, un po 'sorprendentemente, può o non può invocare l'ultimo. – Cameron

+0

@ Cameron: Grazie. Suppongo che stavo dando per scontato che, se ne hai finalmente, anche tu gestisci le eccezioni. Ma suppongo che sia possibile avere un problema che gestisce solo eccezioni specifiche; o un tentativo/finalmente senza una presa. – GendoIkari

risposta

10

Si comporta davvero come un tentativo/finalmente, quindi se l'applicazione termina, la risorsa non può essere smaltita ... e di solito è ok, perché normalmente lo smaltimento è per il rilascio di risorse detenute dal processo ... e il Il sistema operativo li rassicurerà comunque sulla morte del processo. (Questo non vuol dire che il metodo di Disposenon sarà essere chiamato ... è proprio come con un normale try/finally.)

Ovviamente se hai un "file di lock" sul file system o qualcosa del genere, sarebbe un problema, ma avresti lo stesso problema di fronte a un'interruzione di corrente, ecc.

+1

Penso che forse l'OP pensava che "non gestito" significasse "non catturato nel blocco immediato try/finally", non "non gestito dall'applicazione nel suo complesso". – adv12

+0

Quindi stai dicendo che un'istruzione Using non può davvero garantire che venga chiamato Dispose, giusto? – TrueEddie

+0

@TrueEddie: In effetti, può solo garantirlo nella stessa misura del solito try/finally. –

5

Ci sono delle eccezioni da cui un programma non può essere ripristinato, in quel caso il blocco finally non eseguire. Ad esempio eccezione di overflow dello stack o eccezione di memoria esaurita.

0

Se l'eccezione si svolge solo termina con un'eccezione non gestita che causa l'arresto anomalo del programma e infine i blocchi non vengono eseguiti con la cessazione dell'esecuzione.

tl; dr Infine i blocchi vengono eseguiti solo in caso di successo o di eccezione gestita.