Ho notato che nessuno ha menzionato nelle loro risposte a questa vecchia domanda che rilasciare un blocco su un'eccezione è una cosa incredibilmente pericolosa da fare. Sì, le istruzioni di blocco in C# hanno semantica "definitiva"; quando il controllo esce normalmente o in modo anomalo, il blocco viene rilasciato. Parli tutti di questo come se fosse una buona cosa, ma è una brutta cosa! La cosa giusta da fare se si dispone di un'area bloccata che genera un'eccezione non gestita è terminare il processo malato immediatamente prima di distruggere altri dati utente, non liberare il blocco e continuare a.
Guardalo in questo modo: immagina di avere un bagno con un lucchetto sulla porta e una fila di persone che aspettano fuori. Una bomba in bagno si spegne uccidendo la persona lì dentro. La tua domanda è "in quella situazione la serratura verrà automaticamente sbloccata in modo che la persona successiva possa entrare in bagno?" Si lo farà. Questa non è una buona cosa. Una bomba è appena esplosa e ha ucciso qualcuno! L'impianto idraulico è probabilmente distrutto, la casa non è più strutturalmente sana e ci potrebbe essere un'altra bomba lì. La cosa giusta da fare è far uscire tutti il più velocemente possibile e demolire l'intera casa.
Voglio dire, riflettere a fondo: se bloccato una regione di codice per leggere da una struttura di dati senza che sia mutata in un altro thread, e qualcosa in quella struttura di dati ha generato un'eccezione, probabilità sono buone che è perché la struttura dei dati è corrotta. I dati dell'utente ora sono incasinati; non vuoi provare a salvare i dati utente a questo punto perché stai quindi salvando dati corrotti. Basta terminare il processo.
Se si è bloccata una regione di codice per eseguire una mutazione senza un altro thread che legge lo stato contemporaneamente, e la mutazione genera, quindi se i dati non erano corrotti prima, è sicuro che ora è. Quale è esattamente lo scenario che il blocco dovrebbe proteggere contro. Ora il codice che è in attesa di leggere quello stato sarà immediatamente avere accesso allo stato corrotto e probabilmente si bloccherà. Ancora una volta, la cosa giusta da fare è terminare il processo.
Non importa come lo si taglia, un'eccezione all'interno di un blocco è cattive notizie. La domanda giusta da porre non è "la mia serratura verrà ripulita in caso di eccezione?" La domanda giusta da porsi è "come faccio a garantire che non ci sia mai un'eccezione all'interno di un lucchetto? E se c'è, allora come posso strutturare il mio programma in modo che le mutazioni vengano riportate ai precedenti stati positivi?"
fonte
2012-02-27 15:49:59
Come un pensiero finale (vedi aggiornamenti) - probabilmente dovresti tenere il blocco solo per la durata della rimozione della coda ... eseguire l'elaborazione ** all'esterno ** della serratura. –
Il codice dopo la cattura viene eseguito perché l'eccezione è gestita – cjk
Grazie, devo averlo perso, dovrei cancellare questa domanda? – Vort3x