2010-04-27 30 views
6

Si consideri il seguente semplice applicazione: un Windows Form creato da una sequenza di "nuova applicazione Windows C#" in VS che è stato modificato in un modo seguente:eccezione Catching in Main() metodo

public static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An unexpected exception was caught."); 
    } 

} 

Form1.cs contiene le seguenti modifiche:

private void Form1_Load(object sender, EventArgs e) 
{ 
    throw new Exception("Error"); 

} 

Se premo F5 in IDE, allora, come mi aspetto, vedo una finestra di messaggio che tale eccezione è stato catturato e l'applicazione si chiude.

Se si passa a Debug (o Release)/bin e si avvia l'eseguibile, viene visualizzata la finestra standard "Eccezione non gestita", ovvero il mio gestore di eccezioni non funziona.

Ovviamente, questo ha qualcosa a che fare con l'eccezione generata da un thread diverso dal quale viene chiamato Application.Run. Ma la domanda rimane: perché il comportamento varia a seconda che l'applicazione sia stata eseguita da IDE o dalla riga di comando? Qual è la prassi migliore per garantire che nessuna eccezione rimanga non gestita nell'applicazione?

+0

@Corvin: controlla una risposta accettata, se ritieni di avere una soluzione alla tua domanda. –

risposta

10

Normalmente Application.ThreadException gestirà l'eccezione nell'evento Load. Otterrai il ThreadExceptionDialog che offre le opzioni Chiudi e Continua.

Ma non quando è collegato un debugger. La clausola catch nel loop dei messaggi che visualizza la finestra di dialogo è intenzionalmente disabilitata in quel caso. Ciò è necessario perché sarebbe molto difficile risolvere i problemi delle eccezioni se tale finestra di dialogo si apre quando si esegue il debug di un programma. Quale catcher non è più attivo, la tua catch clause nel metodo Main() ora ottiene un colpo all'eccezione.

È possibile renderlo coerente utilizzando Application.SetUnhandledExceptionMode() nel metodo Main(). Non si dovrebbe, eccezioni in realtà sono difficile eseguire il debug se si esegue questa operazione. Se si desidera personalizzare la gestione delle eccezioni per il thread UI allora si dovrebbe registrare il proprio gestore Application.ThreadException:

if (!System.Diagnostics.Debugger.IsAttached) 
    Application.ThreadException += myThreadException; 

Trapping eccezioni non gestite in thread di lavoro richiede un gestore AppDomain.UnhandledException. Non sono recuperabili.

Inoltre, fare attenzione a un errore in Windows a 64 bit, le eccezioni nell'evento di caricamento vengono inghiottite senza diagnostica quando è collegato un debugger. Forza la modalità AnyCPU per evitare quella trap.

+0

@Hans - ti riferisci all'evento 'Form.Load'? A proposito, bella riscrittura. –

+0

@Peter: sì. Grazie! –

Problemi correlati