Best practice per la gestione delle eccezioni in un'applicazione Windows Form?


118

Al momento sto scrivendo la mia prima applicazione Windows Forms. Ho letto alcuni libri di C # ora, quindi ho una conoscenza relativamente buona di quali funzionalità del linguaggio C # deve affrontare le eccezioni. Tuttavia, sono tutti abbastanza teorici, quindi ciò che non ho ancora è un'idea di come tradurre i concetti di base in un buon modello di gestione delle eccezioni nella mia applicazione.

Qualcuno vorrebbe condividere qualche perla di saggezza sull'argomento? Pubblica eventuali errori comuni che hai visto fare a neofiti come me e qualsiasi consiglio generale sulla gestione delle eccezioni in modo da rendere la mia applicazione più stabile e robusta.

Le cose principali che sto attualmente cercando di capire sono:

  • Quando dovrei lanciare nuovamente un'eccezione?
  • Dovrei provare ad avere un meccanismo centrale di gestione degli errori di qualche tipo?
  • La gestione delle eccezioni che potrebbero essere generate ha un impatto sulle prestazioni rispetto al test preventivo di cose come l'esistenza di un file su disco?
  • Tutto il codice eseguibile dovrebbe essere racchiuso in blocchi try-catch-latest?
  • Ci sono momenti in cui un blocco catch vuoto potrebbe essere accettabile?

Tutti i consigli ricevuti con gratitudine!

Risposte:


79

Qualche altro bit ...

È assolutamente necessario disporre di una politica di gestione delle eccezioni centralizzata. Questo può essere semplice come eseguire il wrapping Main()di un try / catch, fallendo velocemente con un grazioso messaggio di errore all'utente. Questo è il gestore delle eccezioni "ultima risorsa".

I controlli preventivi sono sempre corretti se fattibili, ma non sempre perfetti. Ad esempio, tra il codice in cui verifichi l'esistenza di un file e la riga successiva in cui lo apri, il file potrebbe essere stato eliminato o qualche altro problema potrebbe impedire l'accesso. Hai ancora bisogno di provare / catturare / finalmente in quel mondo. Usa sia il controllo preventivo che il try / catch / latest come appropriato.

Mai "ingoiare" un'eccezione, tranne nei casi più ben documentati in cui si è assolutamente, positivamente sicuri che l'eccezione lanciata sia vivibile. Questo non sarà quasi mai il caso. (E se lo è, assicurati di ingoiare solo la classe di eccezione specifica - non ingoiare maiSystem.Exception .)

Durante la creazione di librerie (utilizzate dalla tua app), non ingoiare eccezioni e non aver paura di far emergere le eccezioni. Non rilanciare a meno che tu non abbia qualcosa di utile da aggiungere. Non farlo mai (in C #):

throw ex;

Come cancellerai lo stack di chiamate. Se è necessario rilanciare (operazione occasionalmente necessaria, ad esempio quando si utilizza il blocco di gestione delle eccezioni di Enterprise Library), utilizzare quanto segue:

throw;

Alla fine della giornata, la stragrande maggioranza delle eccezioni lanciate da un'applicazione in esecuzione dovrebbe essere esposta da qualche parte. Non dovrebbero essere esposti agli utenti finali (poiché spesso contengono dati proprietari o comunque preziosi), ma piuttosto di solito registrati, con gli amministratori informati dell'eccezione. All'utente può essere presentata una finestra di dialogo generica, magari con un numero di riferimento, per semplificare le cose.

La gestione delle eccezioni in .NET è più arte che scienza. Ognuno avrà i suoi preferiti da condividere qui. Questi sono solo alcuni dei suggerimenti che ho raccolto utilizzando .NET sin dal primo giorno, tecniche che mi hanno salvato la pancetta in più di un'occasione. Il tuo chilometraggio può variare.


1
Se si lascia che le eccezioni si manifestino, come si suppone che il chiamante sappia se l'eccezione indica che un'operazione non è riuscita ma ma il sistema è fondamentalmente a posto (ad esempio un utente ha tentato di aprire un file di documento corrotto; il file non viene caricato, ma tutto altrimenti dovrebbe andare bene), o se indica che la CPU è in fiamme e che bisogna dirigersi verso le uscite il più velocemente possibile? Qualcosa come ArgumentException potrebbe indicare entrambi, a seconda delle circostanze in cui viene lanciato.
supercat

2
@supercat Scrivendo sottoclassi specifiche di ApplicationExceptionquei casi di fallimento che l'applicazione dovrebbe ragionevolmente essere in grado di differenziare e gestire.
Matt Enright

@ Matt Enright: Certamente è possibile cogliere le proprie eccezioni, ma non sono a conoscenza di qualcosa che assomigli lontanamente a una convenzione in base alla quale i moduli che generano eccezioni indicano se indicano la corruzione di uno stato esterno al di là di ciò che è implicito nel fallimento. Idealmente, un metodo come SuperDocument.CreateFromFile () potrebbe avere successo, generare un'eccezione CleanFailure o generare un'eccezione SomethingReallyBadHappenedException. Sfortunatamente, a meno che non si avvolga tutto ciò che potrebbe generare un'eccezione all'interno del proprio blocco catch, non c'è modo di sapere se
un'eccezione

@ Matt Enright: ... dovrebbe essere racchiuso in un CleanFailureException o in un SomethingReallyBadHappenedException. E avvolgere tutto in singoli blocchi try-catch vanificherebbe l'intero scopo di avere eccezioni in primo luogo.
supercat

2
Penso che sia un progetto di libreria scadente, per nascondere le modalità di errore con un tipo di eccezione impreciso. Non generare un'eccezione FileNotFoundException se ciò che intendi effettivamente è IOException o InvalidDataException, poiché l'applicazione deve rispondere in modo diverso a ogni caso. Cose come StackOverflowException o OutOfMemoryException non possono essere ragionevolmente gestite da un'applicazione, quindi lascia che si gonfino, poiché un'applicazione ben comportata ha comunque il gestore centralizzato di "ultima istanza".
Matt Enright

63

C'è un ottimo articolo CodeProject qui . Ecco un paio di punti salienti:

  • Pianifica il peggio *
  • Controllalo presto
  • Non fidarti dei dati esterni
  • Gli unici dispositivi affidabili sono: il video, il mouse e la tastiera.
  • Anche le scritture possono fallire
  • Codice in sicurezza
  • Non lanciare una nuova eccezione ()
  • Non inserire informazioni importanti sull'eccezione nel campo Messaggio
  • Metti una singola cattura (eccezione ex) per thread
  • Le eccezioni generiche rilevate dovrebbero essere pubblicate
  • Log Exception.ToString (); non registrare mai solo Exception.Message!
  • Non catturare (eccezione) più di una volta per thread
  • Non ingoiare mai eccezioni
  • Il codice di pulizia dovrebbe essere inserito in blocchi finali
  • Usa "usando" ovunque
  • Non restituire valori speciali in condizioni di errore
  • Non utilizzare eccezioni per indicare l'assenza di una risorsa
  • Non utilizzare la gestione delle eccezioni come mezzo per restituire informazioni da un metodo
  • Usa eccezioni per errori che non dovrebbero essere ignorati
  • Non cancellare la traccia dello stack quando si genera nuovamente un'eccezione
  • Evita di modificare le eccezioni senza aggiungere valore semantico
  • Le eccezioni devono essere contrassegnate come [Serializzabile]
  • In caso di dubbio, non affermare, lancia un'eccezione
  • Ogni classe di eccezione dovrebbe avere almeno i tre costruttori originali
  • Fai attenzione quando usi l'evento AppDomain.UnhandledException
  • Non reinventare la ruota
  • Non utilizzare la gestione degli errori non strutturata (VB.Net)

3
Ti dispiacerebbe spiegarmi un po 'di più questo punto? "Non usare le eccezioni per indicare l'assenza di una risorsa" Non sono abbastanza sicuro di averne compreso il motivo. Anche solo un'osservazione: questa risposta non spiega affatto il "perché". So che ha 5 anni ma ancora mi infastidisce un po '
Rémi

Il collegamento all'articolo a cui si fa riferimento è scaduto. Code Project suggerisce che l'articolo potrebbe essere stato spostato qui .
DavidRR

15

Tieni presente che Windows Form ha il proprio meccanismo di gestione delle eccezioni. Se si fa clic su un pulsante nel modulo e il relativo gestore genera un'eccezione che non viene rilevata nel gestore, Windows Form visualizzerà la propria finestra di dialogo Eccezioni non gestite.

Per impedire la visualizzazione della finestra di dialogo delle eccezioni non gestite e rilevare tali eccezioni per la registrazione e / o per fornire la propria finestra di dialogo di errore, è possibile collegarsi all'evento Application.ThreadException prima della chiamata a Application.Run () nel metodo Main ().


Grazie per questo suggerimento, l'ho imparato troppo tardi, l'ho appena verificato in linqpad, funziona come previsto, il delegato è: void Form1_UIThreadException (object sender, ThreadExceptionEventArgs t) Un'altra buona fonte su questo argomento è richnewman.wordpress.com/2007/ 04/08 /… Per la gestione complessiva delle eccezioni non gestite: l'evento AppDomain.UnhandledException è per le eccezioni non gestite generate dal thread dell'interfaccia utente non principale.
zhaorufei

14

Tutti i consigli pubblicati qui finora sono buoni e vale la pena prestare attenzione.

Una cosa su cui vorrei espandere è la tua domanda "La gestione delle eccezioni che potrebbero essere generate ha un impatto sulle prestazioni rispetto al test preventivo di cose come l'esistenza di un file su disco?"

L'ingenua regola pratica è "i blocchi try / catch sono costosi". Non è proprio vero. Provare non è costoso. È il trucco, in cui il sistema deve creare un oggetto Exception e caricarlo con la traccia dello stack, che è costoso. Ci sono molti casi in cui l'eccezione è, beh, abbastanza eccezionale che va benissimo racchiudere il codice in un blocco try / catch.

Ad esempio, se stai compilando un dizionario, questo:

try
{
   dict.Add(key, value);
}
catch(KeyException)
{
}

è spesso più veloce che farlo:

if (!dict.ContainsKey(key))
{
   dict.Add(key, value);
}

per ogni singolo elemento che stai aggiungendo, perché l'eccezione viene generata solo quando aggiungi una chiave duplicata. (Le query di aggregazione LINQ lo fanno.)

Nell'esempio che hai fornito, userei try / catch quasi senza pensarci. Primo, solo perché il file esiste quando lo controlli non significa che esisterà quando lo apri, quindi dovresti comunque gestire l'eccezione.

Secondo, e penso che sia più importante, a meno che tu non a) il tuo processo stia aprendo migliaia di file eb) le probabilità che un file che sta cercando di aprire non esista non sono banalmente basse, il rendimento di creare l'eccezione non è qualcosa che tu ' te ne accorgerai mai. In generale, quando il tuo programma tenta di aprire un file, sta solo cercando di aprire un file. Questo è un caso in cui scrivere codice più sicuro sarà quasi certamente meglio che scrivere il codice più veloce possibile.


3
nel caso di dict, puoi semplicemente fare: dict[key] = valueche dovrebbe essere veloce se non più veloce ..
nawfal

9

Ecco alcune linee guida che seguo

  1. Fail-Fast: questa è più una linea guida per la generazione di eccezioni, per ogni presupposto che fai e ogni parametro che stai inserendo in una funzione fai un controllo per assicurarti di iniziare con i dati giusti e che i presupposti stai facendo sono corrette. I controlli tipici includono, argomento non nullo, argomento nell'intervallo previsto ecc.

  2. Quando si lancia di nuovo, conserva la traccia dello stack - Questo si traduce semplicemente nell'utilizzo di throw durante il rilancio invece di lanciare una nuova eccezione (). In alternativa, se ritieni di poter aggiungere più informazioni, racchiudi l'eccezione originale come eccezione interna. Ma se stai intercettando un'eccezione solo per registrarla, usa sicuramente throw;

  3. Non intercettare eccezioni che non puoi gestire, quindi non preoccuparti di cose come OutOfMemoryException perché se si verificano non sarai in grado di fare molto comunque.

  4. Aggancia i gestori di eccezioni globali e assicurati di registrare quante più informazioni possibili. Per i winform, agganciare gli eventi di eccezione non gestiti sia appdomain che thread.

  5. Le prestazioni dovrebbero essere prese in considerazione solo quando hai analizzato il codice e hai visto che sta causando un collo di bottiglia delle prestazioni, per impostazione predefinita ottimizza per leggibilità e design. Quindi, riguardo alla tua domanda originale sul controllo dell'esistenza del file, direi che dipende, se puoi fare qualcosa per evitare che il file sia presente, allora sì, fallo controllare altrimenti se tutto ciò che devi fare è lanciare un'eccezione se il file è non c'è allora non vedo il punto.

  6. Ci sono sicuramente momenti in cui sono richiesti blocchi di cattura vuoti, penso che le persone che dicono il contrario non hanno lavorato su basi di codice che si sono evolute in diverse versioni. Ma dovrebbero essere commentati e rivisti per assicurarsi che siano davvero necessari. L'esempio più tipico è quello degli sviluppatori che utilizzano try / catch per convertire la stringa in un numero intero invece di utilizzare ParseInt ().

  7. Se ti aspetti che il chiamante del tuo codice sia in grado di gestire le condizioni di errore, crea eccezioni personalizzate che descrivano in dettaglio la situazione non esclusa e forniscano informazioni pertinenti. Altrimenti, attenersi il più possibile ai tipi di eccezione incorporati.


A cosa serve agganciare i gestori di eccezioni non gestite sia appdomain che thread? Se usi solo Appdomain.UnhandledException, non è quello più generico che catturerà tutto?
Quagmire

Intendevi gestire l' Application.ThreadExceptionevento quando hai fatto riferimento all'evento "eccezione non gestita thread"?
Jeff B

4

Mi piace la filosofia di non prendere nulla che non intendo maneggiare, qualunque cosa significhi maneggiare nel mio contesto particolare.

Odio quando vedo codice come:

try
{
   // some stuff is done here
}
catch
{
}

L'ho visto di tanto in tanto ed è abbastanza difficile trovare problemi quando qualcuno "mangia" le eccezioni. Un collega che ho avuto fa questo e tende a finire per contribuire a un flusso costante di problemi.

Rigetto se c'è qualcosa che la mia particolare classe deve fare in risposta a un'eccezione, ma il problema deve essere chiarito per chiamare il metodo in cui è successo.

Penso che il codice dovrebbe essere scritto in modo proattivo e che le eccezioni dovrebbero essere per situazioni eccezionali, non per evitare di testare le condizioni.


@Kiquenet Scusa, ero un po 'poco chiaro. Cosa intendevo: non eseguire tali catture vuote, aggiungi invece un gestore a Dispatcher.UnhandledException e aggiungi almeno un log in modo che non venga mangiato senza breadcrumb :) Ma a meno che tu non abbia il requisito di un componente silenzioso dovresti comunque includere eccezioni nel tuo design. Lanciali quando devono essere lanciati, stipula contratti chiari per interfacce / API / qualsiasi classe.
LuckyLikey

4

Sto solo uscendo, ma ti darò una breve panoramica su dove utilizzare la gestione delle eccezioni. Cercherò di affrontare gli altri tuoi punti quando torno :)

  1. Verifica esplicitamente tutte le condizioni di errore note *
  2. Aggiungi una prova / cattura attorno al codice se non sei sicuro di essere stato in grado di gestire tutti i casi
  3. Aggiungi un try / catch attorno al codice se l'interfaccia .NET che stai chiamando genera un'eccezione
  4. Aggiungi una prova / cattura attorno al codice se supera una soglia di complessità per te
  5. Aggiungi una prova / cattura attorno al codice se per un controllo di integrità: stai affermando CHE QUESTO NON DOVREBBE MAI ACCADERE
  6. Come regola generale, non utilizzo le eccezioni in sostituzione dei codici di ritorno. Questo va bene per .NET, ma non per me. Tuttavia, ho delle eccezioni (hehe) a questa regola, dipende anche dall'architettura dell'applicazione su cui stai lavorando.

*Entro limiti ragionevoli. Non è necessario controllare se, ad esempio, un raggio cosmico ha colpito i tuoi dati provocando il capovolgimento di un paio di bit. Capire cosa sia "ragionevole" è un'abilità acquisita per un ingegnere. È difficile da quantificare, ma facile da intuire. Cioè, posso facilmente spiegare perché uso una prova / cattura in un caso particolare, ma mi è difficile infondere un altro con la stessa conoscenza.

Io per primo tendo ad allontanarmi dalle architetture fortemente basate sulle eccezioni. try / catch non ha un impatto sulle prestazioni in quanto tale, l'hit arriva quando viene lanciata l'eccezione e il codice potrebbe dover salire di diversi livelli dello stack di chiamate prima che qualcosa lo gestisca.


4

La regola d'oro a cui si è cercato di attenersi è gestire l'eccezione il più vicino possibile alla fonte.

Se devi lanciare nuovamente un'eccezione, prova ad aggiungerla, rilanciare un'eccezione FileNotFoundException non aiuta molto, ma lanciare un'eccezione ConfigurationFileNotFoundException consentirà di catturarla e di agire da qualche parte a monte della catena.

Un'altra regola che cerco di seguire è di non usare try / catch come una forma di flusso di programma, quindi verifico file / connessioni, mi assicuro che gli oggetti siano stati avviati, ecc .. prima di usarli. Try / catch dovrebbe essere per le eccezioni, cose che non puoi controllare.

Per quanto riguarda un blocco catch vuoto, se stai facendo qualcosa di importante nel codice che ha generato l'eccezione, dovresti rilanciare l'eccezione come minimo. Se non ci sono conseguenze del codice che ha generato l'eccezione non è in esecuzione perché l'hai scritto in primo luogo.


Questa "regola d'oro" è arbitraria nella migliore delle ipotesi.
Evan Harper

3

puoi intercettare l'evento ThreadException.

  1. Seleziona un progetto di applicazione Windows in Esplora soluzioni.

  2. Aprire il file Program.cs generato facendo doppio clic su di esso.

  3. Aggiungere la seguente riga di codice all'inizio del file di codice:

    using System.Threading;
  4. Nel metodo Main (), aggiungi quanto segue come prima riga del metodo:

    Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
  5. Aggiungi quanto segue sotto il metodo Main ():

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
        // Do logging or whatever here
        Application.Exit();
    }
  6. Aggiungi codice per gestire l'eccezione non gestita all'interno del gestore eventi. Qualsiasi eccezione che non viene gestita in qualsiasi altra parte dell'applicazione viene gestita dal codice precedente. Più comunemente, questo codice dovrebbe registrare l'errore e visualizzare un messaggio all'utente.

refrence: https://blogs.msmvps.com/deborahk/global-exception-handler-winforms/


@Kiquenet mi dispiace, non so di VB
Omid-RH

2

Le eccezioni sono costose ma necessarie. Non è necessario racchiudere tutto in un tentativo di cattura, ma è necessario assicurarsi che alla fine vengano sempre rilevate le eccezioni. Molto dipenderà dal tuo design.

Non rilanciare se lasciare che l'eccezione aumenti andrà altrettanto bene. Non lasciare mai che gli errori passino inosservati.

esempio:

void Main()
{
  try {
    DoStuff();
  }
  catch(Exception ex) {
    LogStuff(ex.ToString());
  }

void DoStuff() {
... Stuff ...
}

Se DoStuff va storto, vorrai comunque che venga rilasciato. L'eccezione verrà lanciata su main e vedrai il treno di eventi nella traccia dello stack di ex.


1

Quando dovrei lanciare nuovamente un'eccezione?

Ovunque, ma metodi per l'utente finale ... come gestori di clic sui pulsanti

Dovrei provare ad avere un meccanismo centrale di gestione degli errori di qualche tipo?

Scrivo un file di registro ... abbastanza facile per un'app WinForm

La gestione delle eccezioni che potrebbero essere generate ha un impatto sulle prestazioni rispetto al test preventivo di cose come l'esistenza di un file su disco?

Non sono sicuro di questo, ma credo che sia una buona pratica per le eccezioni ... Voglio dire che puoi chiedere se un file esiste e se non genera un'eccezione FileNotFoundException

Tutto il codice eseguibile dovrebbe essere racchiuso in blocchi try-catch-latest?

yeap

Ci sono momenti in cui un blocco catch vuoto potrebbe essere accettabile?

Sì, diciamo che vuoi mostrare una data, ma non hai idea di come quella data sia stata memorizzata (gg / mm / aaaa, mm / gg / aaaa, ecc.) Provi ad analizzarla ma se fallisce vai avanti .. se per te è irrilevante ... direi di sì, c'è


1

L'unica cosa che ho imparato molto rapidamente è stata racchiudere assolutamente ogni pezzo di codice che interagisce con qualsiasi cosa al di fuori del flusso del mio programma (ad esempio file system, chiamate al database, input dell'utente) con blocchi try-catch. Try-catch può incorrere in un calo delle prestazioni, ma di solito in questi punti del codice non sarà visibile e si ripagherà con sicurezza.

Ho usato blocchi di cattura vuoti in luoghi in cui l'utente potrebbe fare qualcosa che non è realmente "errato", ma può generare un'eccezione ... un esempio che mi viene in mente è in un GridView se l'utente DoubleCLick il segnaposto grigio cella in alto a sinistra attiverà l'evento CellDoubleClick, ma la cella non appartiene a una riga. In tal caso, tu non lo ha davvero bisogno di postare un messaggio, ma se non lo prendi genererà un errore di eccezione non gestita all'utente.


1

Quando si rilancia un'eccezione, la parola chiave viene generata da sola. Questo genererà l'eccezione catturata e sarà ancora in grado di utilizzare lo stack trace per vedere da dove proviene.

Try
{
int a = 10 / 0;
}
catch(exception e){
//error logging
throw;
}

facendo ciò, la traccia dello stack terminerà nell'istruzione catch. (evita questo)

catch(Exception e)
// logging
throw e;
}

questo vale ancora per le versioni più recenti di .NET Framework e .NET Core?
LuckyLikey

1

Nella mia esperienza ho ritenuto opportuno cogliere le eccezioni quando so che le creerò. Per i casi in cui mi trovo in un'applicazione Web e sto eseguendo una Response.Redirect, so che riceverò un'eccezione System.ThreadAbortException. Dal momento che è intenzionale, ho solo una presa per il tipo specifico e lo ingoio.

try
{
/*Doing stuff that may cause an exception*/
Response.Redirect("http:\\www.somewhereelse.com");
}
catch (ThreadAbortException tex){/*Ignore*/}
catch (Exception ex){/*HandleException*/}

1

Condivido profondamente la regola di:

  • Non lasciare mai che gli errori passino inosservati.

Il motivo è che:

  • Quando scrivi per la prima volta il codice, molto probabilmente non avrai la piena conoscenza del codice di 3 parti, della lirica .NET FCL o degli ultimi contributi dei tuoi colleghi. In realtà non puoi rifiutarti di scrivere codice finché non conosci bene ogni possibilità di eccezione. Così
  • Trovo costantemente di usare try / catch (Exception ex) solo perché voglio proteggermi da cose sconosciute e, come hai notato, prendo l'eccezione, non la più specifica come OutOfMemoryException ecc. E faccio sempre l'eccezione essere saltato su a me (o al QA) da ForceAssert.AlwaysAssert (false, ex.ToString ());

ForceAssert.AlwaysAssert è il mio modo personale di Trace.Assert, indipendentemente dal fatto che la macro DEBUG / TRACE sia definita.

Il ciclo di sviluppo forse: ho notato la brutta finestra di dialogo Assert o qualcun altro me ne è lamentato, poi torno al codice e capisco il motivo per sollevare l'eccezione e decido come elaborarlo.

In questo modo posso scrivere il MIO codice in breve tempo e proteggermi da un dominio sconosciuto, ma essendo sempre notato se accadevano cose anormali, in questo modo il sistema è diventato più sicuro e più sicuro.

So che molti di voi non saranno d'accordo con me perché uno sviluppatore dovrebbe conoscere ogni dettaglio del suo codice, francamente, sono anche un purista ai vecchi tempi. Ma oggigiorno ho imparato che la politica di cui sopra è più pragmatica.

Per il codice WinForms, una regola d'oro a cui obbedisco sempre è:

  • Prova sempre / cattura (eccezione) il codice del gestore eventi

questo proteggerà la tua interfaccia utente essendo sempre utilizzabile.

Per il calo delle prestazioni, la riduzione delle prestazioni si verifica solo quando il codice raggiunge il catch, l'esecuzione del codice try senza l'eccezione effettiva sollevata non ha alcun effetto significativo.

L'eccezione dovrebbe avvenire con poche possibilità, altrimenti non sono eccezioni.


-1

Devi pensare all'utente. Il crash dell'applicazione è l' ultimocosa che l'utente vuole. Pertanto, qualsiasi operazione che può fallire dovrebbe avere un blocco try catch a livello dell'interfaccia utente. Non è necessario utilizzare try catch in tutti i metodi, ma ogni volta che l'utente fa qualcosa deve essere in grado di gestire eccezioni generiche. Ciò non ti libera dal controllare tutto per evitare eccezioni nel primo caso, ma non esiste un'applicazione complessa senza bug e il sistema operativo può facilmente aggiungere problemi imprevisti, quindi devi anticipare l'imprevisto e assicurarti se un utente vuole usarne uno operazione non ci sarà perdita di dati perché l'app si arresta in modo anomalo. Non è necessario che la tua app si blocchi, se si rilevano eccezioni non sarà mai in uno stato indeterminato e l'utente è SEMPRE disturbato da un arresto anomalo. Anche se l'eccezione è al massimo livello, non arrestarsi in modo anomalo significa che l'utente può riprodurre rapidamente l'eccezione o almeno registrare il messaggio di errore e quindi aiutarti notevolmente a risolvere il problema. Sicuramente molto di più che ricevere un semplice messaggio di errore e quindi vedere solo la finestra di dialogo di errore di Windows o qualcosa del genere.

Ecco perché non devi MAI essere presuntuoso e pensare che la tua app non abbia bug, questo non è garantito. Ed è uno sforzo molto piccolo per racchiudere alcuni tentativi di catturare blocchi sul codice appropriato e mostrare un messaggio di errore / registrare l'errore.

Come utente, mi arrabbio seriamente ogni volta che un browser o un'app per ufficio o qualsiasi altra cosa si blocca. Se l'eccezione è così alta che l'app non può continuare, è meglio visualizzare quel messaggio e dire all'utente cosa fare (riavviare, correggere alcune impostazioni del sistema operativo, segnalare il bug, ecc.) Piuttosto che andare in crash e basta.


Puoi provare a scrivere risposte meno come uno sproloquio e invece cercare di essere più specifico e provare a dimostrare il tuo punto? Dai anche un'occhiata a Come rispondere .
LuckyLikey
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.