Il codice del metodo principale interamente all’interno di try / catch: è una ctriggers pratica?

Di solito metto tutto il mio codice di metodo Main all’interno di un blocco try / catch in questo modo:

public static void Main(string[] args) { try { // code } catch (Exception e) { // code } } 

Lo faccio nel caso in cui eventuali eccezioni riescano a scivolare fuori dal resto della logica del programma, permettendomi così di fare qualcosa al riguardo, come visualizzarlo in console, registrarlo in un file, ecc. Tuttavia, mi è stato detto questa è una ctriggers pratica

Pensi che sia una ctriggers pratica?

Avvolgere qualsiasi pezzo di codice in un blocco try / catch senza una buona ragione è una ctriggers pratica.

Nel modello di programmazione .NET, le eccezioni dovrebbero essere riservate a casi o condizioni veramente eccezionali. Dovresti solo cercare di individuare le eccezioni alle quali puoi effettivamente fare qualcosa . Inoltre, non dovresti quasi mai prendere la class System.Exception base (ma preferisci piuttosto catturare le classi di eccezioni derivate più specifiche che puoi gestire). E nel caso che si verifichi un’eccezione davvero inaspettata durante l’esecuzione del programma, in realtà dovresti bloccarti.

Ovviamente la risposta “corretta” dovrebbe essere fatta caso per caso, a seconda di cosa succede all’interno di quel // code segnaposto di // code nel blocco catch . Ma se stai chiedendo una regola generale o “best practice”, dovresti sempre avere una ragione specifica per prendere le eccezioni, non solo avvolgere tutto il tuo codice in un blocco try / catch gigantesco, naturalmente senza pensarci .

Tieni presente che se stai semplicemente cercando di rilevare eventuali eccezioni non gestite che potrebbero verificarsi ai fini della registrazione o della segnalazione degli errori, dovresti utilizzare l’ evento AppDomain.UnhandledException . Si tratta di un evento di sola notifica, pertanto non consente di gestire tali eccezioni, ma è il posto giusto per implementare la funzionalità di registrazione o segnalazione degli errori dopo l’arresto anomalo dell’applicazione.


EDIT: Mentre stavo recuperando la lettura dell’eccellente blog di Raymond Chen, “The Old New Thing” , ho notato che di recente aveva pubblicato un articolo su un argomento simile. È specifico per COM, piuttosto che per .NET Framework, ma i concetti generali relativi alla gestione degli errori sono ugualmente applicabili a entrambi gli ambienti. Ho pensato di condividere un paio di gemme dell’articolo qui, a sostegno della mia opinione [apparentemente abbastanza controversa].

Storicamente, la COM ha posto una prova gigantesca / eccetto i metodi del tuo server. Se il tuo server ha riscontrato quella che normalmente sarebbe un’eccezione non gestita, il gigante try / except lo RPC_E_SERVERFAULT e lo trasformsrà nell’errore RPC_E_SERVERFAULT . Quindi ha contrassegnato l’eccezione come gestita, in modo che il server rimanesse attivo, quindi “migliorando la robustezza mantenendo il server in esecuzione anche quando si è verificato un problema.”

Intendiamoci, questo era in realtà un disservizio.

Il fatto che si sia verificata un’eccezione non gestita indica che il server si trovava in uno stato imprevisto. Osservando l’eccezione e dicendo “Non preoccuparti, va tutto bene”, finisci per lasciare un server corrotto in esecuzione.

[. . . ]

L’acquisizione di tutte le eccezioni e il proseguimento del processo presuppongono che un server possa essere ripristinato da un errore imprevisto. Ma questo è assurdo. Sai già che il server è irrecuperabilmente tostato: si è schiantato!

Molto meglio è lasciare che il server si arresti in modo tale che il crash dump possa essere catturato nel punto dell’errore. Ora hai una possibilità di combattere per capire cosa sta succedendo.

Puoi [e dovresti] leggere l’intero articolo qui sul suo blog: Come distriggersre il gestore di eccezioni che COM “utile” avvolge attorno al tuo server .

Se stai facendo la cosa più intelligente che puoi con l’errore, è una buona pratica. Questo è ciò che try / catch è per.

Se stai semplicemente buttando via l’errore (o loggandolo e gettandolo via) – specialmente se lo fai indipendentemente dal tipo di eccezione – è considerato una ctriggers pratica.

Questo potrebbe sollevare la domanda: cosa succede se la cosa più intelligente è registrarla e buttarla via? Voglio dire che sarebbe un caso eccezionale. Ma in pratica, il mio codice affermerebbe diversamente. Credo che mi conceda molte cattive pratiche.

Sono d’accordo con il 90% di ciò che dice Cody. Ci sono alcune situazioni simili all’esempio pluggin in cui potresti voler catturare le eccezioni di sistema. Ecco un altro esempio di considerare il consumo di un servizio Web WCF .

Obiettivo : consumare il servizio e smaltirlo anche se si verifica un errore. Consentire l’errore di bolla.

 public static bool DoRemoteWebServiceWork() { bool result; RemoteWebServiceClient client = new RemoteWebServiceClient(); try { result = client.DoWork(); client.Close(); } catch (Exception) { client.Abort(); //dispose throw;//This service is critical to application function. The application should break if an exception is thrown. //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code. } return result; } 

Obiettivo : consumare il servizio e smaltirlo anche se si verifica un errore. Prevenire l’errore di gorgogliare.

 public static bool DoRemoteWebServiceWork() { bool result; RemoteWebServiceClient client = new RemoteWebServiceClient(); try { result = client.DoWork(); client.Close(); } catch (Exception) { client.Abort(); //dispose //throw; //This service is auxiliary to the applications primary function. We have no influence over the service and therefore cannot fix it. //could log end point and binding exceptions to avoid ignoring changes to the remote service that require updates to our code. } return result; } 

Sicuramente, sì, è una ctriggers pratica, usare la class Exception

Dovresti preoccuparti dei tipi di un’eccezione, non tagliare tutte le eccezioni sul blocco catch, impedendo loro di informare il sistema dell’errore.

La class Exception è una class base e, è ansible che un’eccezione di primo livello sia inclusa nel codice. Utilizza le eccezioni più specifiche nel blocco catch, in particolare, l’unica che, che il codice solleva in un blocco try {…} catch {…}, e solo se può essere efficacemente risolto a quel particolare livello (in un funzione, dove try .. catch block è dichiarato)

Dipende da cosa fai se riscontri un errore. Se riesci a cogliere tutti gli errori che sembrano gestirli con grazia – ctriggers pratica. Direi che è una ctriggers pratica anche se si accede solo lì – accedere localmente.

Se davvero fai qualcosa per recuperare l’errore (ad esempio lo hai lanciato tu stesso e sai cosa fare al riguardo) – Io voterei OK 🙂